Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed references to IDAD in utils.py #1017

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d992701
Merge pull request #988 from microsoft/main
daxpryce Sep 16, 2022
dc0a566
Fix seaborn syntax
bdpedigo Sep 16, 2022
899a470
Increment bugfix version
bdpedigo Sep 16, 2022
64d2f7e
Exclude 3.6.1
hugwuoke Oct 11, 2022
357c933
Update setup.cfg
hugwuoke Oct 11, 2022
d2bd257
Update README.md
ktwillcode Oct 9, 2022
194678d
Fixed graph matching with similarity matrix of unequal dimensions (#1…
dokato Dec 8, 2022
5bc51bd
Edited contributing guidelines (#1000)
hugwuoke Dec 9, 2022
1a2bdf9
Update setup.cfg (#999)
bdpedigo Dec 9, 2022
a410de9
Added release notes for 2.0.1 (#1003)
bdpedigo Dec 9, 2022
8ceadda
add 3.10, remove 3.7 from metadata
bdpedigo Jan 4, 2023
c19672c
make tests go vroom
bdpedigo Jan 4, 2023
b25f36c
run black
bdpedigo Jan 4, 2023
f6a4c30
run isort
bdpedigo Jan 4, 2023
5e33804
ban gensim 4.2.0
bdpedigo Jan 4, 2023
9ac2405
bump major version
bdpedigo Jan 4, 2023
7844bce
fix toc
bdpedigo Jan 4, 2023
349cc77
Hard capped networkx version to avoid incompatability (#1016)
alyakin314 Jan 9, 2023
2fb6e1c
Closing issue 970
w3schools-test Jan 10, 2023
342f88b
Merge branch 'dev' into my-feature
hugwuoke Jan 10, 2023
c9ab3b7
Removing IDAD tests
w3schools-test Jan 13, 2023
f0c2a57
correcting formating
w3schools-test Mar 2, 2023
9635f79
Corrected deprecation warnings (#1019)
hugwuoke Mar 2, 2023
71fcd00
Merge branch 'dev' into my-feature
bdpedigo Mar 2, 2023
33809fb
Corrected contributing guidelines (#1014)
hugwuoke Mar 14, 2023
844fdce
Merge branch 'dev' into my-feature
bdpedigo Mar 14, 2023
968b93e
Changing the symmetrize function to include both binary and non binar…
w3schools-test Mar 24, 2023
2075c7d
Merge branch 'my-feature' of https://github.com/hugwuoke/graspologic …
w3schools-test Mar 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Expand Up @@ -89,7 +89,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python_version: ["3.7", "3.8", "3.9"]
python_version: ["3.8", "3.9", "3.10"]
fail-fast: false
steps:
- uses: actions/checkout@v2
Expand Down
7 changes: 3 additions & 4 deletions CONTRIBUTING.md
Expand Up @@ -71,7 +71,7 @@ branch using a virtual environment. Steps:
right of the page. This creates a copy of the code under your GitHub user account. For more details on how to
fork a repository see [this guide](https://help.github.com/articles/fork-a-repo/).

2. Clone your fork of the `graspologic` repo from your GitHub account to your local disk:
2. Clone your fork of the `graspologic` repo from your GitHub account to your local disk. Do this by typing the following into command prompt or the equivelant on your operating system:

```bash
git clone git@github.com:YourGithubAccount/graspologic.git
Expand All @@ -87,8 +87,7 @@ branch using a virtual environment. Steps:
Always use a `feature` branch. Pull requests directly to either `dev` or `main` will be rejected
until you create a feature branch based on `dev`.

4. From the project root, create a [virtual environment](https://docs.python.org/3/library/venv.html) and install all development dependencies. Examples using various terminals are provided below. These examples use Python 3.8 but you may use any Python version supported by graspologic. These commands should install `graspologic` in editable mode, as well as
all of its dependencies and several tools you need for developing `graspologic`.
4. From the project root, create a [virtual environment](https://docs.python.org/3/library/venv.html) and install all development dependencies. Examples using various terminals are provided below. These examples use Python 3.8 but you may use any Python version supported by graspologic. If using Python 3.8 does not work feel free to type the same command simply using "Python" instead of "Python 3.8".These commands should install `graspologic` in editable mode, as well as all of its dependencies and several tools you need for developing `graspologic`. These commands assume that your operating system has already activated virtual environments which will allow virtual environments to be created.

**Bash**
```bash
Expand All @@ -104,7 +103,7 @@ all of its dependencies and several tools you need for developing `graspologic`.
```
**CMD (Windows)**
```cmd
rem Create virtual environment. Depending on your installation you might need "py -3.8 -m venv venv" instead
rem Create virtual environment. Depending on your installation you might need "py -3 -m venv venv" instead
python3.8 -m venv venv

rem Activate the virtual environment
Expand Down
10 changes: 8 additions & 2 deletions README.md
@@ -1,9 +1,9 @@
<!-- omit in toc -->
# graspologic
[![Paper shield](https://img.shields.io/badge/JMLR-Paper-red)](http://www.jmlr.org/papers/volume20/19-490/19-490.pdf)
[![PyPI version](https://img.shields.io/pypi/v/graspologic.svg)](https://pypi.org/project/graspologic/)
[![Downloads shield](https://pepy.tech/badge/graspologic)](https://pepy.tech/project/graspologic)
![graspologic CI](https://github.com/microsoft/graspologic/workflows/graspologic%20CI/badge.svg)
[![DOI](https://zenodo.org/badge/147768493.svg)](https://zenodo.org/badge/latestdoi/147768493)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## `graspologic` is a package for graph statistical algorithms.
Expand All @@ -15,6 +15,7 @@
- [Contributing](#contributing)
- [License](#license)
- [Issues](#issues)
- [Citing `graspologic`](#citing-graspologic)

# Overview
A graph, or network, provides a mathematically intuitive representation of data with some sort of relationship between items. For example, a social network can be represented as a graph by considering all participants in the social network as nodes, with connections representing whether each pair of individuals in the network are friends with one another. Naively, one might apply traditional statistical techniques to a graph, which neglects the spatial arrangement of nodes within the network and is not utilizing all of the information present in the graph. In this package, we provide utilities and algorithms designed for the processing and analysis of graphs with specialized graph statistical algorithms.
Expand All @@ -25,31 +26,36 @@ The official documentation with usage is at https://microsoft.github.io/graspolo
Please visit the [tutorial section](https://microsoft.github.io/graspologic/latest/tutorials/index.html) in the official website for more in depth usage.

# System Requirements
<!-- omit in toc -->
## Hardware requirements
`graspologic` package requires only a standard computer with enough RAM to support the in-memory operations.

<!-- omit in toc -->
## Software requirements
<!-- omit in toc -->
### OS Requirements
`graspologic` is tested on the following OSes:
- Linux x64
- macOS x64
- Windows 10 x64

And across the following **x86_64** versions of Python:
- 3.7
- 3.8
- 3.9
- 3.10

If you try to use `graspologic` for a different platform than the ones listed and notice any unexpected behavior,
please feel free to [raise an issue](https://github.com/microsoft/graspologic/issues/new). It's better for ourselves and our users
if we have concrete examples of things not working!

# Installation Guide
<!-- omit in toc -->
## Install from pip
```
pip install graspologic
```

<!-- omit in toc -->
## Install from Github
```
git clone https://github.com/microsoft/graspologic
Expand Down
9 changes: 9 additions & 0 deletions docs/reference/release.rst
Expand Up @@ -3,6 +3,15 @@
Release Log
===========

graspologic 2.0.1
-----------------
- Fixed bug with a matplotlib version incompatibility
`#996 <https://github.com/microsoft/graspologic/pull/996>`
- Fixed graph matching with similarity matrix of unequal dimensions
`#1002 <https://github.com/microsoft/graspologic/pull/1002>`
- Fixed bug with missing typing-extensions dependency
`#999 <https://github.com/microsoft/graspologic/pull/999>`

graspologic 2.0.0
-----------------
- Refactored graph matching code and added many new features
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/embedding/CovariateAssistedEmbed.ipynb
Expand Up @@ -139,7 +139,7 @@
"def plot_latents(latent_positions, *, title, labels, ax=None):\n",
" if ax is None:\n",
" ax = plt.gca()\n",
" plot = sns.scatterplot(latent_positions[:, 0], latent_positions[:, 1], hue=labels, \n",
" plot = sns.scatterplot(x=latent_positions[:, 0], y=latent_positions[:, 1], hue=labels, \n",
" linewidth=0, s=10, ax=ax, palette=\"Set1\")\n",
" plot.set_title(title, wrap=True);\n",
" ax.axes.xaxis.set_visible(False)\n",
Expand Down
1 change: 0 additions & 1 deletion graspologic/align/orthogonal_procrustes.py
Expand Up @@ -55,7 +55,6 @@ class OrthogonalProcrustes(BaseAlign):
def __init__(
self,
) -> None:

super().__init__()

def fit(self, X: np.ndarray, Y: np.ndarray) -> "OrthogonalProcrustes":
Expand Down
1 change: 0 additions & 1 deletion graspologic/cluster/divisive_cluster.py
Expand Up @@ -122,7 +122,6 @@ def __init__(
max_level: int = 4,
delta_criter: float = 0,
):

_check_common_inputs(min_components, max_components, cluster_kws)

if cluster_method not in ["gmm", "kmeans"]:
Expand Down
12 changes: 7 additions & 5 deletions graspologic/match/solver.py
Expand Up @@ -169,6 +169,9 @@ def __init__(
_compare_dimensions(B, AB, "row", "column", "B", "AB")
_compare_dimensions(A, BA, "row", "column", "A", "BA")
_compare_dimensions(B, BA, "row", "row", "B", "BA")
if S is not None:
_compare_dimensions(A, [S], "row", "row", "A", "S")
_compare_dimensions(B, [S], "column", "column", "B", "S")

# padding for unequally sized inputs
if self.n_A != self.n_B:
Expand All @@ -189,9 +192,11 @@ def __init__(
# check for similarity term
if S is None:
S = csr_array((self.n, self.n))
elif self.padded:
S = _adj_pad(S, n_padded=self.n, method="naive")

_compare_dimensions(A, [S], "row", "row", "A", "S")
_compare_dimensions(B, [S], "row", "column", "B", "S")
_compare_dimensions(B, [S], "column", "column", "B", "S")

self.A = A
self.B = B
Expand Down Expand Up @@ -643,9 +648,7 @@ def _multilayer_adj_pad(
return new_matrices


def _adj_pad(
matrix: AdjacencyMatrix, n_padded: Int, method: PaddingType
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
def _adj_pad(matrix: AdjacencyMatrix, n_padded: Int, method: PaddingType) -> np.ndarray:
if isinstance(matrix, (csr_matrix, csr_array)) and (method == "adopted"):
msg = (
"Using adopted padding method with a sparse adjacency representation; this "
Expand Down Expand Up @@ -691,7 +694,6 @@ def _compare_dimensions(
def _check_partial_match(
partial_match: Optional[Union[np.ndarray, Tuple]], n1: int, n2: int
) -> np.ndarray:

_partial_match: np.ndarray
if partial_match is None:
_partial_match = np.array([[], []]).T
Expand Down
1 change: 0 additions & 1 deletion graspologic/models/edge_swaps.py
Expand Up @@ -46,7 +46,6 @@ class EdgeSwapper:

@beartype
def __init__(self, adjacency: AdjacencyMatrix, seed: Optional[int] = None):

weight_check = is_unweighted(adjacency)
check_argument(weight_check, "adjacency must be unweighted")

Expand Down
1 change: 0 additions & 1 deletion graspologic/nominate/spectralVN.py
Expand Up @@ -121,7 +121,6 @@ def _check_y(self, y: np.ndarray) -> None:
)

def _check_params(self) -> None:

if self.n_neighbors is not None and type(self.n_neighbors) is not int:
raise TypeError("k must be an integer")
elif self.n_neighbors is not None and self.n_neighbors <= 0:
Expand Down
5 changes: 2 additions & 3 deletions graspologic/partition/leiden.py
Expand Up @@ -138,7 +138,7 @@ def _community_python_to_native(
if starting_communities is None:
return None
native_safe: Dict[str, int] = {}
for (node_id, partition) in starting_communities.items():
for node_id, partition in starting_communities.items():
node_id_as_str = identity(node_id)
native_safe[node_id_as_str] = partition
return native_safe
Expand Down Expand Up @@ -399,7 +399,6 @@ def _from_native(
native_cluster: gn.HierarchicalCluster,
identifier: _IdentityMapper,
) -> HierarchicalCluster:

if not isinstance(native_cluster, gn.HierarchicalCluster):
raise TypeError(
"This class method is only valid for graspologic_native.HierarchicalCluster"
Expand All @@ -420,7 +419,7 @@ def hierarchical_leiden(
List[Tuple[Any, Any, Union[int, float]]],
nx.Graph,
np.ndarray,
scipy.sparse.csr.csr_matrix,
scipy.sparse.csr_matrix,
],
max_cluster_size: int = 1000,
starting_communities: Optional[Dict[str, int]] = None,
Expand Down
2 changes: 1 addition & 1 deletion graspologic/pipeline/embed/adjacency_spectral_embedding.py
Expand Up @@ -180,7 +180,7 @@ def adjacency_spectral_embedding(

node_labels = np.array(list(graph.nodes()))

graph_as_csr = nx.to_scipy_sparse_matrix(
graph_as_csr = nx.to_scipy_sparse_array(
graph, weight=used_weight_attribute, nodelist=node_labels
)

Expand Down
2 changes: 1 addition & 1 deletion graspologic/pipeline/embed/laplacian_spectral_embedding.py
Expand Up @@ -196,7 +196,7 @@ def laplacian_spectral_embedding(

node_labels = np.array(list(graph.nodes()))

graph_as_csr = nx.to_scipy_sparse_matrix(
graph_as_csr = nx.to_scipy_sparse_array(
graph, weight=used_weight_attribute, nodelist=node_labels
)

Expand Down
2 changes: 1 addition & 1 deletion graspologic/pipeline/embed/omnibus_embedding.py
Expand Up @@ -296,7 +296,7 @@ def _augment_graph(
weight_attribute: Optional[str],
perform_augment_diagonal: bool = True,
) -> np.ndarray:
graph_sparse = nx.to_scipy_sparse_matrix(
graph_sparse = nx.to_scipy_sparse_array(
graph, weight=weight_attribute, nodelist=node_ids
)

Expand Down
1 change: 0 additions & 1 deletion graspologic/plot/plot.py
Expand Up @@ -996,7 +996,6 @@ def _distplot(
xlabel: str = "",
ylabel: str = "Density",
) -> matplotlib.pyplot.Axes:

plt.figure(figsize=figsize)
ax = plt.gca()
palette = sns.color_palette(palette)
Expand Down
1 change: 0 additions & 1 deletion graspologic/plot/plot_matrix.py
Expand Up @@ -812,7 +812,6 @@ def matrixplot( # type: ignore
# in the opposite order
rev_group = list(col_group[::-1])
for i, sc in enumerate(rev_group):

# Add a new axis when needed
tick_ax = divider.append_axes(
"top", size="1%", pad=col_tick_pad[i], sharex=ax
Expand Down
30 changes: 15 additions & 15 deletions graspologic/utils/utils.py
Expand Up @@ -286,7 +286,8 @@ def is_almost_symmetric(


def symmetrize(
graph: Union[np.ndarray, csr_matrix], method: Literal["avg", "triu", "tril"] = "avg"
graph: Union[np.ndarray, csr_matrix],
method: Literal["w_avg", "avg", "triu", "tril"] = "avg",
) -> Union[np.ndarray, csr_matrix]:
"""
A function for forcing symmetry upon a graph.
Expand All @@ -296,13 +297,15 @@ def symmetrize(
graph: object
Either array-like, (n_vertices, n_vertices) numpy matrix or csr_matrix

method: {'avg' (default), 'triu', 'tril',}, optional
method: {'w_avg' (default), 'triu', 'tril',}, optional
An option indicating which half of the edges to
retain when symmetrizing.

- 'avg'
- 'w_avg'
Retain the average weight between the upper and lower
right triangle, of the adjacency matrix.
- "avg"
Performs the same function as "w_avg" but outputs a binearized matrix.
- 'triu'
Retain the upper right triangle.
- 'tril'
Expand Down Expand Up @@ -332,8 +335,10 @@ def symmetrize(
graph = pac.triu(graph)
elif method == "tril":
graph = pac.tril(graph)
elif method == "avg":
elif method == "w_avg":
graph = (pac.triu(graph) + pac.tril(graph)) / 2
elif method == "avg":
graph = binarize((pac.triu(graph) + pac.tril(graph)) / 2)
else:
msg = "You have not passed a valid parameter for the method."
raise ValueError(msg)
Expand Down Expand Up @@ -367,7 +372,7 @@ def remove_loops(graph: GraphRepresentation) -> Union[np.ndarray, csr_matrix]:
return graph


LaplacianFormType = Literal["I-DAD", "DAD", "R-DAD"]
LaplacianFormType = Literal["DAD", "R-DAD"]


def to_laplacian(
Expand All @@ -378,8 +383,8 @@ def to_laplacian(
r"""
A function to convert graph adjacency matrix to graph Laplacian.

Currently supports I-DAD, DAD, and R-DAD Laplacians, where D is the diagonal matrix
of degrees of each node, I is the identity matrix, and A is the adjacency matrix.
Currently supports DAD and R-DAD Laplacians, where D is the diagonal matrix
of degrees of each node and A is the adjacency matrix.

R-DAD is regularized Laplacian: where :math:`D_t = D + regularizer \times I`.

Expand All @@ -389,10 +394,8 @@ def to_laplacian(
Either array-like, (n_vertices, n_vertices) numpy array,
scipy.sparse.csr_matrix, or an object of type networkx.Graph.

form: {'I-DAD', 'DAD' (default), 'R-DAD'}, string, optional
form: {'DAD' (default), 'R-DAD'}, string, optional

- 'I-DAD'
Computes :math:`L = I - D_i^{-1/2} A D_i^{-1/2}`
- 'DAD'
Computes :math:`L = D_o^{-1/2} A D_i^{-1/2}`
- 'R-DAD'
Expand Down Expand Up @@ -432,7 +435,7 @@ def to_laplacian(

"""

valid_inputs = ["I-DAD", "DAD", "R-DAD"]
valid_inputs = ["DAD", "R-DAD"]
if form not in valid_inputs:
raise TypeError("Unsuported Laplacian normalization")

Expand Down Expand Up @@ -468,10 +471,7 @@ def to_laplacian(
in_root = diag(in_root) # just change to sparse diag for sparse support
out_root = diag(out_root)

if form == "I-DAD":
L = diag(in_degree) - A
L = in_root @ L @ in_root
elif form == "DAD" or form == "R-DAD":
if form == "DAD" or form == "R-DAD":
L = out_root @ A @ in_root
if is_symmetric(A):
return symmetrize(
Expand Down
1 change: 0 additions & 1 deletion runtime.txt

This file was deleted.