Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@ repos:
stages: [commit]
- id: end-of-file-fixer
stages: [commit]
- id: trailing-whitespace
# - repo: https://github.com/pycqa/isort
# rev: 5.10.1
# hooks:
# - id: isort
# stages: [commit]
- repo: https://github.com/psf/black
rev: 22.3.0
hooks:
- id: black
language_version: python3
exclude: 'pymathics/graph/version.py'
- repo: https://github.com/pycqa/flake8
rev: 3.9.2
hooks:
- id: flake8
stages: [commit]
stages: [commit]
# - repo: https://github.com/pycqa/flake8
# rev: 3.9.2
# hooks:
# - id: flake8
# stages: [commit]
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
# remake --tasks to shows the targets and the comments

GIT2CL ?= admin-tools/git2cl
PYTHON ?= python3
PIP ?= pip3
PYTHON ?= python
PIP ?= $(PYTHON) -m pip
RM ?= rm

.PHONY: all build \
Expand Down Expand Up @@ -40,7 +40,7 @@ install: pypi-setup
$(PYTHON) setup.py install

# Run tests
check: pytest doctest
test check: pytest

#: Remove derived files
clean: clean-pyc
Expand All @@ -51,7 +51,7 @@ clean-pyc:

#: Run py.test tests. Use environment variable "o" for pytest options
pytest:
py.test test $o
$(PYTHON) -m pytest test $o


# #: Create data that is used to in Django docs and to build TeX PDF
Expand Down
5 changes: 2 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ Example Session
::

$ mathicsscript
Mathicscript: 5.0.0, Mathics 5.0.0
Mathicscript: 5.0.0, Mathics 6.0.0
on CPython 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0]
using SymPy 1.9, mpmath 1.2.1, numpy 1.21.5
matplotlib 3.5.2,
Asymptote version 2.81

Copyright (C) 2011-2022 The Mathics Team.
Copyright (C) 2011-2023 The Mathics3 Team.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
Expand All @@ -23,7 +23,6 @@ Example Session
Quit by pressing CONTROL-D

In[1]:= LoadModule["pymathics.graph"]

Out[1]= pymathics.graph
In[2]:= BinomialTree[3]
In[3]:= BinomialTree[6]
Expand Down
50 changes: 45 additions & 5 deletions pymathics/graph/__init__.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,64 @@
"""Pymathics Graph - Working with Graphs (Vertices and Edges)
"""
Graphs - Vertices and Edges

This module provides functions and variables for workting with
graphs.
A Pymathics module that provides functions and variables for working with graphs.

Example:
In[1]:= LoadModule["pymathics.graph"]
Out[1]= pymathics.graph
In[2]:= BinomialTree[3]
In[3]:= BinomialTree[6]
In[4]:= CompleteKaryTree[3, VertexLabels->True]

Networkx does the heavy lifting here.
"""

from pymathics.graph.__main__ import * # noqa
from pymathics.graph.base import (
AcyclicGraphQ,
BetweennessCentrality,
ClosenessCentrality,
ConnectedGraphQ,
DegreeCentrality,
DirectedEdge,
DirectedGraphQ,
EdgeConnectivity,
EdgeIndex,
EdgeList,
EdgeRules,
EigenvectorCentrality,
FindShortestPath,
FindVertexCut,
Graph,
GraphBox,
HITSCentrality,
HighlightGraph,
KatzCentrality,
LoopFreeGraphQ,
MixedGraphQ,
MultigraphQ,
PageRankCentrality,
PlanarGraphQ,
PathGraphQ,
Property,
PropertyValue,
SimpleGraphQ,
UndirectedEdge,
VertexAdd,
VertexConnectivity,
VertexDelete,
VertexIndex,
VertexList,
)

from pymathics.graph.measures_and_metrics import EdgeCount, VertexCount, VertexDegree

from pymathics.graph.algorithms import * # noqa
from pymathics.graph.generators import * # noqa
from pymathics.graph.tree import * # noqa
from pymathics.graph.version import __version__ # noqa

pymathics_version_data = {
"author": "The Mathics Team",
"author": "The Mathics3 Team",
"version": __version__,
"name": "Graph",
"requires": ["networkx"],
Expand Down
41 changes: 23 additions & 18 deletions pymathics/graph/algorithms.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
# -*- coding: utf-8 -*-
"""
Algorithms on Graphs.

networkx does all the heavy lifting.
Algorithms on Graphs
"""

from typing import Optional

from mathics.core.convert.expression import to_mathics_list
from mathics.core.convert.python import from_python
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
from mathics.core.list import ListExpression
from mathics.core.symbols import SymbolFalse
from mathics.core.systemsymbols import SymbolDirectedInfinity

from pymathics.graph.__main__ import (
from pymathics.graph.base import (
DEFAULT_GRAPH_OPTIONS,
SymbolDirectedEdge,
SymbolUndirectedEdge,
Expand All @@ -25,7 +26,7 @@
class ConnectedComponents(_NetworkXBuiltin):
"""
## >> g = Graph[{1 -> 2, 2 -> 3, 3 <-> 4}]; ConnectedComponents[g]
## = {{4, 3}, {2}, {1}}
## = {{3, 4}, {2}, {1}}

## >> g = Graph[{1 -> 2, 2 -> 3, 3 -> 1}]; ConnectedComponents[g]
## = {{1, 2, 3}}
Expand All @@ -34,7 +35,9 @@ class ConnectedComponents(_NetworkXBuiltin):
## = {{4, 5}, {1, 2, 3}}
"""

def apply(self, graph, expression, evaluation, options):
def eval(
self, graph, expression, evaluation: Evaluation, options: dict
) -> Optional[ListExpression]:
"ConnectedComponents[graph_, OptionsPattern[%(name)s]]"
graph = self._build_graph(graph, evaluation, options, expression)
if graph:
Expand All @@ -54,10 +57,10 @@ def apply(self, graph, expression, evaluation, options):
# <dd>returns a Hamiltonian path in the given tournament graph.
# </dl>
# """
# def apply_(self, graph, expression, evaluation, options):
# "%(name)s[graph_, OptionsPattern[%(name)s]]"
# def eval_(self, graph, expression, evaluation: Evaluation, options):
# "FindHamiltonianPath[graph_, OptionsPattern[FindHamiltonPath]]"

# graph = self._build_graph(graph, evaluation, options, expression)
# graph = self._build_graph(graph, evaluation: Evaluation, options, expression)
# if graph:
# # FIXME: for this to work we need to fill in all O(n^2) edges as an adjacency matrix?
# path = nx.algorithms.tournament.hamiltonian_path(graph.G)
Expand Down Expand Up @@ -106,17 +109,19 @@ class GraphDistance(_NetworkXBuiltin):
= GraphDistance[{1 -> 2}, 3, 4]
"""

def apply_s(self, graph, s, expression, evaluation, options):
"%(name)s[graph_, s_, OptionsPattern[%(name)s]]"
def eval_s(
self, graph, s, expression, evaluation: Evaluation, options: dict
) -> Optional[ListExpression]:
"GraphDistance[graph_, s_, OptionsPattern[GraphDistance]]"
graph = self._build_graph(graph, evaluation, options, expression)
if graph:
weight = graph.update_weights(evaluation)
d = nx.shortest_path_length(graph.G, source=s, weight=weight)
inf = Expression(SymbolDirectedInfinity, 1)
return to_mathics_list(*[d.get(v, inf) for v in graph.vertices])

def apply_s_t(self, graph, s, t, expression, evaluation, options):
"%(name)s[graph_, s_, t_, OptionsPattern[%(name)s]]"
def eval_s_t(self, graph, s, t, expression, evaluation: Evaluation, options: dict):
"GraphDistance[graph_, s_, t_, OptionsPattern[GraphDistance]]"
graph = self._build_graph(graph, evaluation, options, expression)
if not graph:
return
Expand Down Expand Up @@ -147,7 +152,7 @@ class FindSpanningTree(_NetworkXBuiltin):

options = DEFAULT_GRAPH_OPTIONS

def apply(self, graph, expression, evaluation, options):
def eval(self, graph, expression, evaluation: Evaluation, options: dict):
"%(name)s[graph_, OptionsPattern[%(name)s]]"
graph = self._build_graph(graph, evaluation, options, expression)
if graph:
Expand Down Expand Up @@ -182,8 +187,8 @@ class PlanarGraphQ(_NetworkXBuiltin):

options = DEFAULT_GRAPH_OPTIONS

def apply(self, graph, expression, evaluation, options):
"%(name)s[graph_, OptionsPattern[%(name)s]]"
def eval(self, graph, expression, evaluation: Evaluation, options: dict):
"PlanarGraphQ[graph_, OptionsPattern[PlanarGraphQ]]"
graph = self._build_graph(graph, evaluation, options, expression)
if not graph:
return SymbolFalse
Expand All @@ -203,8 +208,8 @@ class WeaklyConnectedComponents(_NetworkXBuiltin):
= {{1, 2, 3, 4, 5}, {6, 7, 8}}
"""

def apply(self, graph, expression, evaluation, options):
"WeaklyConnectedComponents[graph_, OptionsPattern[%(name)s]]"
def eval(self, graph, expression, evaluation: Evaluation, options):
"WeaklyConnectedComponents[graph_, OptionsPattern[WeaklyConnectedComponents]]"
graph = self._build_graph(graph, evaluation, options, expression)
if graph:
components = nx.connected_components(graph.G.to_undirected())
Expand Down
Loading