topologicpy 0.7.72__py3-none-any.whl → 0.7.73__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- topologicpy/CellComplex.py +58 -0
- topologicpy/Graph.py +96 -0
- topologicpy/Plotly.py +0 -2
- topologicpy/version.py +1 -1
- {topologicpy-0.7.72.dist-info → topologicpy-0.7.73.dist-info}/METADATA +1 -1
- {topologicpy-0.7.72.dist-info → topologicpy-0.7.73.dist-info}/RECORD +9 -9
- {topologicpy-0.7.72.dist-info → topologicpy-0.7.73.dist-info}/WHEEL +1 -1
- {topologicpy-0.7.72.dist-info → topologicpy-0.7.73.dist-info}/LICENSE +0 -0
- {topologicpy-0.7.72.dist-info → topologicpy-0.7.73.dist-info}/top_level.txt +0 -0
topologicpy/CellComplex.py
CHANGED
@@ -1006,6 +1006,64 @@ class CellComplex():
|
|
1006
1006
|
shells = Topology.Shells(cellComplex)
|
1007
1007
|
return shells
|
1008
1008
|
|
1009
|
+
@staticmethod
|
1010
|
+
def Torus(origin= None, majorRadius: float = 0.5, minorRadius: float = 0.125, uSides: int = 16, vSides: int = 8, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001):
|
1011
|
+
"""
|
1012
|
+
Creates a torus.
|
1013
|
+
|
1014
|
+
Parameters
|
1015
|
+
----------
|
1016
|
+
origin : topologic_core.Vertex , optional
|
1017
|
+
The origin location of the torus. The default is None which results in the torus being placed at (0, 0, 0).
|
1018
|
+
majorRadius : float , optional
|
1019
|
+
The major radius of the torus. The default is 0.5.
|
1020
|
+
minorRadius : float , optional
|
1021
|
+
The minor radius of the torus. The default is 0.1.
|
1022
|
+
uSides : int , optional
|
1023
|
+
The number of sides along the longitude of the torus. The default is 16.
|
1024
|
+
vSides : int , optional
|
1025
|
+
The number of sides along the latitude of the torus. The default is 8.
|
1026
|
+
direction : list , optional
|
1027
|
+
The vector representing the up direction of the torus. The default is [0, 0, 1].
|
1028
|
+
placement : str , optional
|
1029
|
+
The description of the placement of the origin of the torus. This can be "bottom", "center", or "lowerleft". It is case insensitive. The default is "center".
|
1030
|
+
tolerance : float , optional
|
1031
|
+
The desired tolerance. The default is 0.0001.
|
1032
|
+
|
1033
|
+
Returns
|
1034
|
+
-------
|
1035
|
+
topologic_core.Cell
|
1036
|
+
The created torus.
|
1037
|
+
|
1038
|
+
"""
|
1039
|
+
|
1040
|
+
from topologicpy.Vertex import Vertex
|
1041
|
+
from topologicpy.Wire import Wire
|
1042
|
+
from topologicpy.Face import Face
|
1043
|
+
from topologicpy.Cell import Cell
|
1044
|
+
from topologicpy.Topology import Topology
|
1045
|
+
|
1046
|
+
if not Topology.IsInstance(origin, "Vertex"):
|
1047
|
+
origin = Vertex.ByCoordinates(0, 0, 0)
|
1048
|
+
if not Topology.IsInstance(origin, "Vertex"):
|
1049
|
+
print("Cell.Torus - Error: The input origin parameter is not a valid topologic vertex. Returning None.")
|
1050
|
+
return None
|
1051
|
+
c = Wire.Circle(origin=Vertex.Origin(), radius=minorRadius, sides=vSides, fromAngle=0, toAngle=360, close=False, direction=[0, 1, 0], placement="center")
|
1052
|
+
c = Face.ByWire(c)
|
1053
|
+
c = Topology.Translate(c, abs(majorRadius-minorRadius), 0, 0)
|
1054
|
+
torus = Topology.Spin(c, origin=Vertex.Origin(), triangulate=False, direction=[0, 0, 1], angle=360, sides=uSides, tolerance=tolerance)
|
1055
|
+
if Topology.Type(torus) == Topology.TypeID("Shell"):
|
1056
|
+
faces = Topology.Faces(torus)
|
1057
|
+
torus = CellComplex.ByFaces(faces)
|
1058
|
+
if placement.lower() == "bottom":
|
1059
|
+
torus = Topology.Translate(torus, 0, 0, minorRadius)
|
1060
|
+
elif placement.lower() == "lowerleft":
|
1061
|
+
torus = Topology.Translate(torus, majorRadius, majorRadius, minorRadius)
|
1062
|
+
|
1063
|
+
torus = Topology.Orient(torus, origin=Vertex.Origin(), dirA=[0, 0, 1], dirB=direction)
|
1064
|
+
torus = Topology.Place(torus, originA=Vertex.Origin(), originB=origin)
|
1065
|
+
return torus
|
1066
|
+
|
1009
1067
|
@staticmethod
|
1010
1068
|
def Vertices(cellComplex) -> list:
|
1011
1069
|
"""
|
topologicpy/Graph.py
CHANGED
@@ -742,6 +742,102 @@ class Graph:
|
|
742
742
|
_ = graph.AllPaths(vertexA, vertexB, True, timeLimit, paths) # Hook to Core
|
743
743
|
return paths
|
744
744
|
|
745
|
+
@staticmethod
|
746
|
+
def AreIsomorphic(graphA, graphB, maxIterations=10, silent=False):
|
747
|
+
"""
|
748
|
+
Tests if the two input graphs are isomorphic according to the Weisfeiler Lehman graph isomorphism test. See https://en.wikipedia.org/wiki/Weisfeiler_Leman_graph_isomorphism_test
|
749
|
+
|
750
|
+
Parameters
|
751
|
+
----------
|
752
|
+
graphA : topologic_core.Graph
|
753
|
+
The first input graph.
|
754
|
+
graphB : topologic_core.Graph
|
755
|
+
The second input graph.
|
756
|
+
maxIterations : int , optional
|
757
|
+
This number limits the number of iterations to prevent the function from running indefinitely, particularly for very large or complex graphs.
|
758
|
+
silent : bool , optional
|
759
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
760
|
+
|
761
|
+
Returns
|
762
|
+
-------
|
763
|
+
bool
|
764
|
+
True if the two input graphs are isomorphic. False otherwise
|
765
|
+
|
766
|
+
"""
|
767
|
+
|
768
|
+
from topologicpy.Topology import Topology
|
769
|
+
|
770
|
+
def weisfeiler_lehman_test(graph1, graph2, max_iterations=10):
|
771
|
+
"""
|
772
|
+
Test if two graphs are isomorphic using the Weisfeiler-Leman (WL) algorithm with early stopping.
|
773
|
+
|
774
|
+
Parameters:
|
775
|
+
graph1 (dict): Adjacency list representation of the first graph.
|
776
|
+
graph2 (dict): Adjacency list representation of the second graph.
|
777
|
+
max_iterations (int): Maximum WL iterations allowed (default is 10).
|
778
|
+
|
779
|
+
Returns:
|
780
|
+
bool: True if the graphs are WL-isomorphic, False otherwise.
|
781
|
+
"""
|
782
|
+
|
783
|
+
def wl_iteration(labels, graph):
|
784
|
+
"""Perform one WL iteration and return updated labels."""
|
785
|
+
new_labels = {}
|
786
|
+
for node in graph:
|
787
|
+
neighborhood_labels = sorted([labels[neighbor] for neighbor in graph[node]])
|
788
|
+
new_labels[node] = (labels[node], tuple(neighborhood_labels))
|
789
|
+
unique_labels = {}
|
790
|
+
count = 0
|
791
|
+
for node in sorted(new_labels):
|
792
|
+
if new_labels[node] not in unique_labels:
|
793
|
+
unique_labels[new_labels[node]] = count
|
794
|
+
count += 1
|
795
|
+
new_labels[node] = unique_labels[new_labels[node]]
|
796
|
+
return new_labels
|
797
|
+
|
798
|
+
# Initialize labels
|
799
|
+
labels1 = {node: 1 for node in graph1}
|
800
|
+
labels2 = {node: 1 for node in graph2}
|
801
|
+
|
802
|
+
for i in range(max_iterations):
|
803
|
+
# Perform WL iteration for both graphs
|
804
|
+
new_labels1 = wl_iteration(labels1, graph1)
|
805
|
+
new_labels2 = wl_iteration(labels2, graph2)
|
806
|
+
|
807
|
+
# Check if the label distributions match
|
808
|
+
if sorted(new_labels1.values()) != sorted(new_labels2.values()):
|
809
|
+
return False
|
810
|
+
|
811
|
+
# Check for stability (early stopping)
|
812
|
+
if new_labels1 == labels1 and new_labels2 == labels2:
|
813
|
+
break
|
814
|
+
|
815
|
+
# Update labels for next iteration
|
816
|
+
labels1, labels2 = new_labels1, new_labels2
|
817
|
+
|
818
|
+
return True
|
819
|
+
|
820
|
+
if not Topology.IsInstance(graphA, "Graph") and not Topology.IsInstance(graphB, "Graph"):
|
821
|
+
if not silent:
|
822
|
+
print("Graph.AreIsomorphic - Error: The input graph parameters are not valid graphs. Returning None.")
|
823
|
+
return None
|
824
|
+
if not Topology.IsInstance(graphA, "Graph"):
|
825
|
+
if not silent:
|
826
|
+
print("Graph.AreIsomorphic - Error: The input graphA parameter is not a valid graph. Returning None.")
|
827
|
+
return None
|
828
|
+
if not Topology.IsInstance(graphB, "Graph"):
|
829
|
+
if not silent:
|
830
|
+
print("Graph.AreIsomorphic - Error: The input graphB parameter is not a valid graph. Returning None.")
|
831
|
+
return None
|
832
|
+
if maxIterations <= 0:
|
833
|
+
if not silent:
|
834
|
+
print("Graph.AreIsomorphic - Error: The input maxIterations parameter is not within a valid range. Returning None.")
|
835
|
+
return None
|
836
|
+
|
837
|
+
g1 = Graph.AdjacencyDictionary(graphA)
|
838
|
+
g2 = Graph.AdjacencyDictionary(graphB)
|
839
|
+
return weisfeiler_lehman_test(g1, g2, max_iterations=maxIterations)
|
840
|
+
|
745
841
|
@staticmethod
|
746
842
|
def AverageClusteringCoefficient(graph, mantissa: int = 6, silent: bool = False):
|
747
843
|
"""
|
topologicpy/Plotly.py
CHANGED
@@ -571,8 +571,6 @@ class Plotly:
|
|
571
571
|
from topologicpy.Color import Color
|
572
572
|
from topologicpy.Dictionary import Dictionary
|
573
573
|
from topologicpy.Helper import Helper
|
574
|
-
for d in dictionaries[:30]:
|
575
|
-
print(Dictionary.Keys(d), Dictionary.Values(d))
|
576
574
|
traces = []
|
577
575
|
x = []
|
578
576
|
y = []
|
topologicpy/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = '0.7.
|
1
|
+
__version__ = '0.7.73'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: topologicpy
|
3
|
-
Version: 0.7.
|
3
|
+
Version: 0.7.73
|
4
4
|
Summary: An AI-Powered Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
|
5
5
|
Author-email: Wassim Jabi <wassim.jabi@gmail.com>
|
6
6
|
License: AGPL v3 License
|
@@ -2,7 +2,7 @@ topologicpy/ANN.py,sha256=XAuUjNvDRK1hhXfo82S-zXmnAPZGEdHJMRdfpu0aJ8I,47901
|
|
2
2
|
topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
|
3
3
|
topologicpy/BVH.py,sha256=mKVCAu9K8qzcWXtPDVH5usXZV1DNNNJl4n3rU5Lh1ZM,12931
|
4
4
|
topologicpy/Cell.py,sha256=2izd-YGqy897_JHHgrGlIo5WwUeEIWVD3KspV1z_sj8,107860
|
5
|
-
topologicpy/CellComplex.py,sha256=
|
5
|
+
topologicpy/CellComplex.py,sha256=5PtnRrDx_3zmtt4aTosxK9XBzZtayzaOC50pkJiIlFY,51170
|
6
6
|
topologicpy/Cluster.py,sha256=51q5G1L5xAzRMfVU8YBXhq0g3g2X9aVNcahU-vYZRrI,55672
|
7
7
|
topologicpy/Color.py,sha256=wPhA7rLr9BTZsWYUUVnQpbmL5ZMkGlDSsa8f3S5B-d4,20250
|
8
8
|
topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
|
@@ -11,13 +11,13 @@ topologicpy/Dictionary.py,sha256=0AsGoz48pGTye_F4KcJopNjD9STeQ50LHc6PPvERFaA,319
|
|
11
11
|
topologicpy/Edge.py,sha256=9u9SdUxuenLUIK26xwFvPoYV34p0dCfXmHHBxdgvAdM,67164
|
12
12
|
topologicpy/EnergyModel.py,sha256=AqTtmXE35SxvRXhG3vYAQd7GQDW-6HtjYPHua6ME4Eg,53762
|
13
13
|
topologicpy/Face.py,sha256=q7x6auTju6IS3mdOhhXZdU3rqKSuJCE-5EOfxofDDMI,124348
|
14
|
-
topologicpy/Graph.py,sha256=
|
14
|
+
topologicpy/Graph.py,sha256=ULniT6Notyt9D-2AGws1B87FiVCV0qQp1bxgD0qpLQY,390517
|
15
15
|
topologicpy/Grid.py,sha256=9N6PE84qCm40TRi2WtlVZSBwXXr47zHpscEpZHg_JW4,18205
|
16
16
|
topologicpy/Helper.py,sha256=Sv35czP_j0oLDeJcN8usswUm4U3auiK1LQ_Z_HBvxxg,21716
|
17
17
|
topologicpy/Honeybee.py,sha256=HfTaEV1R8K1xOVQQy9sBOhBTF_ap8A2RxZOYhirp_Mw,21835
|
18
18
|
topologicpy/Matrix.py,sha256=umgR7An919-wGInXJ1wpqnoQ2jCPdyMe2rcWTZ16upk,8079
|
19
19
|
topologicpy/Neo4j.py,sha256=t52hgE9cVsqkGc7m7fjRsLnyfRHakVHwdvF4ms7ow78,22342
|
20
|
-
topologicpy/Plotly.py,sha256
|
20
|
+
topologicpy/Plotly.py,sha256=-Ewc-MPR7wI0Ml_NHoBOMLAJQjFTZRAPbSvVcv9q_Wg,118227
|
21
21
|
topologicpy/Polyskel.py,sha256=EFsuh2EwQJGPLiFUjvtXmAwdX-A4r_DxP5hF7Qd3PaU,19829
|
22
22
|
topologicpy/PyG.py,sha256=LU9LCCzjxGPUM31qbaJXZsTvniTtgugxJY7y612t4A4,109757
|
23
23
|
topologicpy/Shell.py,sha256=8OJjlWk9eCZ3uGOTht6ZVrcMczCafw-YWoDGueaz7eg,87673
|
@@ -28,9 +28,9 @@ topologicpy/Vector.py,sha256=A1g83zDHep58iVPY8WQ8iHNrSOfGWFEzvVeDuMnjDNY,33078
|
|
28
28
|
topologicpy/Vertex.py,sha256=ZS6xK89JKokBKc0W8frdRhhuzR8c-dI1TTLt7pTf1iA,71032
|
29
29
|
topologicpy/Wire.py,sha256=eVet2OToVsXi9AkDYo35LpfMPqJ6aKGD6QkiU4-Jvs8,182271
|
30
30
|
topologicpy/__init__.py,sha256=vlPCanUbxe5NifC4pHcnhSzkmmYcs_UrZrTlVMsxcFs,928
|
31
|
-
topologicpy/version.py,sha256=
|
32
|
-
topologicpy-0.7.
|
33
|
-
topologicpy-0.7.
|
34
|
-
topologicpy-0.7.
|
35
|
-
topologicpy-0.7.
|
36
|
-
topologicpy-0.7.
|
31
|
+
topologicpy/version.py,sha256=_EZM97Nx9ZHcqJT-3j_L8-CxcswiiAnQpZx_aTh--Yc,23
|
32
|
+
topologicpy-0.7.73.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
|
33
|
+
topologicpy-0.7.73.dist-info/METADATA,sha256=DXCQK7AXT5405KD8O3PBcTDNL0gEjLfwM802I_H8QH4,10493
|
34
|
+
topologicpy-0.7.73.dist-info/WHEEL,sha256=a7TGlA-5DaHMRrarXjVbQagU3Man_dCnGIWMJr5kRWo,91
|
35
|
+
topologicpy-0.7.73.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
|
36
|
+
topologicpy-0.7.73.dist-info/RECORD,,
|
File without changes
|
File without changes
|