Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
python-diagrams
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
Valentin Bruch
python-diagrams
Commits
0d149b84
Commit
0d149b84
authored
Feb 9, 2020
by
Valentin Bruch
Browse files
Options
Downloads
Patches
Plain Diff
new feature: Keldysh diagrams
parent
dc2e9457
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
diagrams.py
+131
-54
131 additions, 54 deletions
diagrams.py
with
131 additions
and
54 deletions
diagrams.py
+
131
−
54
View file @
0d149b84
...
@@ -26,7 +26,7 @@ class BaseTeX(object):
...
@@ -26,7 +26,7 @@ class BaseTeX(object):
def
tikz
(
self
,
position
=
''
):
def
tikz
(
self
,
position
=
''
):
'
Return TikZ code for drawing self.
'
'
Return TikZ code for drawing self.
'
return
''
return
r
'
\coordinate[%s] (%s);
'
%
(
position
,
self
.
identifier
)
def
left
(
self
):
def
left
(
self
):
'
Return TikZ node id of leftmost subnode.
'
'
Return TikZ node id of leftmost subnode.
'
...
@@ -43,6 +43,7 @@ class Vertex(BaseTeX):
...
@@ -43,6 +43,7 @@ class Vertex(BaseTeX):
Each vertex consists of n circles to which contraction lines are attached.
Each vertex consists of n circles to which contraction lines are attached.
'''
'''
def
__init__
(
self
,
def
__init__
(
self
,
contour
,
n
,
n
,
label
=
''
,
label
=
''
,
radius
=
0.5
,
radius
=
0.5
,
...
@@ -51,6 +52,7 @@ class Vertex(BaseTeX):
...
@@ -51,6 +52,7 @@ class Vertex(BaseTeX):
draw_color
=
'
black
'
draw_color
=
'
black
'
):
):
super
().
__init__
()
super
().
__init__
()
self
.
contour
=
contour
self
.
n
=
n
# rank of the vertex
self
.
n
=
n
# rank of the vertex
self
.
label
=
label
self
.
label
=
label
self
.
radius
=
radius
self
.
radius
=
radius
...
@@ -102,6 +104,9 @@ class Vertex(BaseTeX):
...
@@ -102,6 +104,9 @@ class Vertex(BaseTeX):
)
)
if
self
.
label
:
if
self
.
label
:
string
+=
'
\n
'
string
+=
'
\n
'
if
self
.
contour
.
keldysh_order
>
0
:
string
+=
r
'
\node[below of=%s] {%s};
'
%
(
self
.
identifier
,
self
.
label
);
else
:
string
+=
r
'
\node[above of=%s] {%s};
'
%
(
self
.
identifier
,
self
.
label
);
string
+=
r
'
\node[above of=%s] {%s};
'
%
(
self
.
identifier
,
self
.
label
);
return
string
return
string
...
@@ -141,9 +146,21 @@ class Contraction:
...
@@ -141,9 +146,21 @@ class Contraction:
shape_style
=
'
,
'
+
self
.
shape_style
shape_style
=
'
,
'
+
self
.
shape_style
else
:
else
:
shape_style
=
''
shape_style
=
''
return
r
'
\draw[%s] (%s) to[out=270, in=270%s] (%s);
'
%
(
try
:
if
self
.
v1
.
contour
.
keldysh_order
>
self
.
v2
.
contour
.
keldysh_order
:
directions
=
(
90
,
270
)
elif
self
.
v1
.
contour
.
keldysh_order
<
self
.
v2
.
contour
.
keldysh_order
:
directions
=
(
270
,
90
)
elif
self
.
v1
.
contour
.
keldysh_order
!=
0
:
directions
=
(
270
,
270
)
else
:
directions
=
(
90
,
90
)
except
:
directions
=
(
270
,
270
)
return
r
'
\draw[%s] (%s) to[out=%d, in=%d%s] (%s);
'
%
(
self
.
style
,
self
.
style
,
self
.
v1
.
getId
(
self
.
idx1
),
self
.
v1
.
getId
(
self
.
idx1
),
*
directions
,
shape_style
,
shape_style
,
self
.
v2
.
getId
(
self
.
idx2
),
self
.
v2
.
getId
(
self
.
idx2
),
)
)
...
@@ -154,12 +171,38 @@ class Interrupt(BaseTeX):
...
@@ -154,12 +171,38 @@ class Interrupt(BaseTeX):
Node interrupting the diagram contour.
Node interrupting the diagram contour.
This can be, e.g., a node ρ separating the two branches of the Keldysh contour.
This can be, e.g., a node ρ separating the two branches of the Keldysh contour.
'''
'''
def
__init__
(
self
,
label
=
''
):
def
__init__
(
self
,
label
=
''
,
**
kwargs
):
super
().
__init__
()
super
().
__init__
()
self
.
label
=
label
self
.
label
=
label
for
key
,
value
in
kwargs
.
items
():
setattr
(
self
,
key
,
value
)
def
tikz
(
self
,
position
=
''
):
def
isKeldysh
(
self
):
return
hasattr
(
self
,
'
keldysh_sep
'
)
def
tikzKeldyshConnect
(
self
,
previous
):
if
getattr
(
self
,
'
keldysh_connect
'
,
None
)
is
None
:
return
''
try
:
assert
self
.
keldysh_direction
==
'
right
'
return
r
'
\draw[%s] (%s) to[out=0, in=0] (%s);
'
%
(
self
.
keldysh_connect
,
previous
.
identifier
,
self
.
identifier
)
except
:
return
r
'
\draw[%s] (%s) to[out=180, in=180] (%s);
'
%
(
self
.
keldysh_connect
,
previous
.
identifier
,
self
.
identifier
)
def
tikz
(
self
,
position
=
''
,
previous
=
None
):
'
Return TikZ code for this interruption.
'
'
Return TikZ code for this interruption.
'
if
self
.
isKeldysh
():
string
=
r
'
\coordinate[yshift=-%s] (%s) at (%s);
'
%
(
self
.
keldysh_sep
,
self
.
identifier
,
previous
.
identifier
)
if
getattr
(
self
,
'
keldysh_label
'
,
''
):
try
:
assert
self
.
keldysh_direction
==
'
right
'
keldysh_label_shift
=
'
1em
'
except
:
keldysh_label_shift
=
'
-1em
'
string
+=
'
\n
'
string
+=
r
'
\path (%s) -- (%s) node[pos=0.5, xshift=%s] {%s};
'
%
(
previous
.
identifier
,
self
.
identifier
,
keldysh_label_shift
,
self
.
keldysh_label
)
return
string
else
:
if
position
:
if
position
:
position
=
'
,
'
+
position
position
=
'
,
'
+
position
return
r
'
\node[fill=white%s] (%s) {%s};
'
%
(
position
,
self
.
identifier
,
self
.
label
)
return
r
'
\node[fill=white%s] (%s) {%s};
'
%
(
position
,
self
.
identifier
,
self
.
label
)
...
@@ -190,6 +233,9 @@ class BaseLine:
...
@@ -190,6 +233,9 @@ class BaseLine:
def
pprint
(
self
):
def
pprint
(
self
):
print
(
self
.
string
,
end
=
''
)
print
(
self
.
string
,
end
=
''
)
def
tikz
(
self
,
node1
,
node2
):
return
r
'
\draw[%s] (%s) -- (%s);
'
%
(
self
.
style
,
node1
.
identifier
,
node2
.
identifier
)
class
Contour
:
class
Contour
:
'''
'''
...
@@ -198,6 +244,7 @@ class Contour:
...
@@ -198,6 +244,7 @@ class Contour:
'''
'''
def
__init__
(
self
):
def
__init__
(
self
):
self
.
elements
=
[]
self
.
elements
=
[]
self
.
keldysh_order
=
-
1
def
pprint
(
self
):
def
pprint
(
self
):
for
e
in
self
.
elements
:
for
e
in
self
.
elements
:
...
@@ -246,6 +293,8 @@ class Diagram:
...
@@ -246,6 +293,8 @@ class Diagram:
\
end
{
pgfonlayer
}
\
end
{
pgfonlayer
}
\
end
{
tikzpicture
}
\
end
{
tikzpicture
}
>>>
# Keldysh diagram (still quite ugly)
>>>
Diagram
(
'
- g12 - g23 - | -- g13 -
'
)
>>>
# Diagram with customized vertice, contraction, base line, and interruption.
>>>
# Diagram with customized vertice, contraction, base line, and interruption.
>>>
d
=
Diagram
()
>>>
d
=
Diagram
()
>>>
d
.
setVertexStyle
(
'
V
'
,
n
=
2
,
label
=
'
$V$
'
)
>>>
d
.
setVertexStyle
(
'
V
'
,
n
=
2
,
label
=
'
$V$
'
)
...
@@ -262,6 +311,7 @@ class Diagram:
...
@@ -262,6 +311,7 @@ class Diagram:
self
.
contractions
=
[]
self
.
contractions
=
[]
self
.
contours
=
[]
self
.
contours
=
[]
self
.
interruptions
=
[]
self
.
interruptions
=
[]
self
.
isKeldysh
=
False
# Properties
# Properties
self
.
sep
=
sep
self
.
sep
=
sep
self
.
sep_unit
=
sep_unit
self
.
sep_unit
=
sep_unit
...
@@ -281,7 +331,7 @@ class Diagram:
...
@@ -281,7 +331,7 @@ class Diagram:
'
~
'
:
dict
(
style
=
'
wiggly, thick
'
)
'
~
'
:
dict
(
style
=
'
wiggly, thick
'
)
}
}
self
.
interrupt_styles
=
{
self
.
interrupt_styles
=
{
'
|
'
:
dict
(
label
=
''
),
'
|
'
:
dict
(
label
=
''
,
keldysh_sep
=
'
4ex
'
,
keldysh_direction
=
'
left
'
,
keldysh_label
=
''
,
keldysh_connect
=
'
thick
'
),
'
ρ
'
:
dict
(
label
=
r
'
$\rho$
'
),
'
ρ
'
:
dict
(
label
=
r
'
$\rho$
'
),
}
}
if
string
:
if
string
:
...
@@ -362,9 +412,11 @@ class Diagram:
...
@@ -362,9 +412,11 @@ class Diagram:
# Start by an interrupt (possibly empty).
# Start by an interrupt (possibly empty).
try
:
try
:
self
.
interruptions
=
[
Interrupt
(
**
self
.
interrupt_styles
[
string
[
0
]])]
self
.
interruptions
=
[
Interrupt
(
**
self
.
interrupt_styles
[
string
[
0
]])]
if
self
.
interruptions
[
-
1
].
isKeldysh
():
self
.
isKeldysh
=
True
string
=
string
[
1
:]
string
=
string
[
1
:]
except
KeyError
:
except
KeyError
:
self
.
interruptions
=
[
Interrupt
()]
self
.
interruptions
=
[
BaseTeX
()]
# Map of open indices: every open index is mapped to it origin (vertex, subindex).
# Map of open indices: every open index is mapped to it origin (vertex, subindex).
vertex_indices
=
{}
vertex_indices
=
{}
...
@@ -379,7 +431,7 @@ class Diagram:
...
@@ -379,7 +431,7 @@ class Diagram:
# Check if c represents a vertex.
# Check if c represents a vertex.
if
c
in
self
.
vertex_styles
:
if
c
in
self
.
vertex_styles
:
# Add a new vertex to the current contour.
# Add a new vertex to the current contour.
self
.
contours
[
-
1
].
elements
.
append
(
Vertex
(
**
self
.
vertex_styles
[
c
]))
self
.
contours
[
-
1
].
elements
.
append
(
Vertex
(
self
.
contours
[
-
1
],
**
self
.
vertex_styles
[
c
]))
# Read the indices for this vertex.
# Read the indices for this vertex.
for
j
in
range
(
self
.
vertex_styles
[
c
][
'
n
'
]):
for
j
in
range
(
self
.
vertex_styles
[
c
][
'
n
'
]):
s
=
string
[
i
+
1
+
j
]
s
=
string
[
i
+
1
+
j
]
...
@@ -412,6 +464,8 @@ class Diagram:
...
@@ -412,6 +464,8 @@ class Diagram:
elif
c
in
self
.
interrupt_styles
.
keys
():
elif
c
in
self
.
interrupt_styles
.
keys
():
# Add an interruption and start a new contour.
# Add an interruption and start a new contour.
self
.
interruptions
.
append
(
Interrupt
(
**
self
.
interrupt_styles
[
c
]))
self
.
interruptions
.
append
(
Interrupt
(
**
self
.
interrupt_styles
[
c
]))
if
self
.
interruptions
[
-
1
].
isKeldysh
():
self
.
isKeldysh
=
True
self
.
contours
.
append
(
Contour
())
self
.
contours
.
append
(
Contour
())
else
:
else
:
# Invalid character in diagram.
# Invalid character in diagram.
...
@@ -465,62 +519,85 @@ class Diagram:
...
@@ -465,62 +519,85 @@ class Diagram:
\tikzset{wiggly/.style={decorate, decoration=snake}}
\tikzset{wiggly/.style={decorate, decoration=snake}}
\tikzset{zigzag/.style={decorate, decoration=zigzag}}
\tikzset{zigzag/.style={decorate, decoration=zigzag}}
'''
'''
# List of all TikZ nodes on the diagram axis combined with the number of prior base lines.
nodes
=
[]
# Begin creating the TikZ picture.
# List of all base line objects with the indices of their starting node: (baseline, index).
print
(
r
'
\begin{tikzpicture}[node distance=%s, baseline=(%s.base)]
'
%
(
node_distance
,
self
.
interruptions
[
0
].
identifier
),
file
=
file
)
baselines
=
{}
# Iterate over contours, interruptions and elements to collect all nodes and baselines.
# Create the first node.
for
i
,
contour
in
enumerate
(
self
.
contours
):
print
(
self
.
interruptions
[
0
].
tikz
(),
file
=
file
)
# Iterate over contours, interruptions and elements to draw vertices and interruptions.
last_node
=
self
.
interruptions
[
0
]
keldysh_order
=
-
1
+
self
.
isKeldysh
for
i
,
contour
in
enumerate
(
self
.
contours
,
1
):
# First draw the contour.
contour
.
keldysh_order
=
keldysh_order
for
j
,
e
in
enumerate
(
contour
.
elements
):
if
type
(
e
)
!=
BaseLine
:
factor
=
getattr
(
contour
.
elements
[
j
-
1
],
'
factor
'
,
1
)
or
1
print
(
e
.
tikz
(
position
=
'
right of=%s, xshift=%g%s
'
%
(
last_node
.
right
(),
factor
*
self
.
sep
,
self
.
sep_unit
)),
file
=
file
)
last_node
=
e
# Then draw the interruption.
try
:
try
:
if
self
.
interruptions
[
i
].
label
:
if
self
.
interruptions
[
i
].
isKeldysh
():
nodes
.
append
(
self
.
interruptions
[
i
])
if
getattr
(
self
.
interruptions
[
i
],
'
keldysh_direction
'
,
'
left
'
)
==
'
left
'
:
print
(
self
.
interruptions
[
i
].
tikz
(
previous
=
self
.
interruptions
[
i
-
1
]),
file
=
file
)
else
:
assert
type
(
last_node
)
==
Interrupt
last_node
=
self
.
interruptions
[
i
]
keldysh_order
+=
1
elif
self
.
interruptions
[
i
].
label
:
factor
=
getattr
(
contour
.
elements
[
-
1
],
'
factor
'
,
1
)
or
1
print
(
self
.
interruptions
[
i
].
tikz
(
position
=
'
right of=%s, xshift=%g%s
'
%
(
last_node
.
right
(),
factor
*
self
.
sep
,
self
.
sep_unit
)),
file
=
file
)
last_node
=
self
.
interruptions
[
i
]
except
:
except
:
pass
pass
for
e
in
contour
.
elements
:
if
type
(
e
)
==
BaseLine
:
baselines
[
len
(
nodes
)
-
1
]
=
e
else
:
nodes
.
append
(
e
)
# Collect trailing interruptions.
# Collect trailing interruptions.
for
i
in
range
(
len
(
self
.
contours
),
len
(
self
.
interruptions
)):
for
i
in
range
(
len
(
self
.
contours
),
len
(
self
.
interruptions
)):
try
:
try
:
if
self
.
interruptions
[
i
].
label
:
if
self
.
interruptions
[
i
].
label
and
not
self
.
interruptions
[
i
].
isKeldysh
()
:
nodes
.
append
(
self
.
interruptions
[
i
]
)
print
(
self
.
interruptions
[
i
].
tikz
(
position
=
'
right of=%s, xshift=%g%s
'
%
(
self
.
interruptions
[
i
-
1
].
identifier
,
self
.
sep
,
self
.
sep_unit
)),
file
=
file
)
except
:
except
:
pass
break
# Begin creating the TikZ picture.
print
(
r
'
\begin{tikzpicture}[node distance=%s, baseline=(%s.base)]
'
%
(
node_distance
,
nodes
[
0
].
identifier
),
file
=
file
)
# Create the first node.
try
:
print
(
nodes
[
0
].
tikz
(),
file
=
file
)
except
:
print
(
'
Error while printing node tikz:
'
,
nodes
[
0
],
file
=
sys
.
stderr
)
# Draw vertices and interruptions (including their labels).
for
i
,
n
in
enumerate
(
nodes
[
1
:]):
try
:
factor
=
baselines
[
i
].
factor
or
1
except
:
factor
=
1
print
(
n
.
tikz
(
position
=
'
right of=%s, xshift=%g%s
'
%
(
nodes
[
i
].
right
(),
factor
*
self
.
sep
,
self
.
sep_unit
)),
file
=
file
)
# Draw the rest on the background.
# Draw the rest on the background.
print
(
r
'
\begin{pgfonlayer}{background}
'
,
file
=
file
)
print
(
r
'
\begin{pgfonlayer}{background}
'
,
file
=
file
)
# Draw base lines.
# Draw base lines.
for
i
,
b
in
baselines
.
items
():
for
i
,
contour
in
enumerate
(
self
.
contours
,
1
):
if
i
<
0
:
# First draw the contour.
# Base line left of all nodes.
if
type
(
contour
.
elements
[
0
])
==
BaseLine
:
print
(
r
'
\coordinate[left of=%s, xshift=-%s%s] (left);
'
%
(
nodes
[
0
].
identifier
,
b
.
factor
*
self
.
sep
,
self
.
sep_unit
),
file
=
file
)
print
(
contour
.
elements
[
0
].
tikz
(
self
.
interruptions
[
i
-
1
],
contour
.
elements
[
1
]),
file
=
file
)
print
(
r
'
\draw[%s] (left) -- (%s);
'
%
(
b
.
style
,
nodes
[
0
].
identifier
),
file
=
file
)
for
j
,
e
in
enumerate
(
contour
.
elements
[
1
:],
1
):
elif
i
>
len
(
nodes
)
-
2
:
if
type
(
e
)
==
BaseLine
:
# Base line right of all nodes.
try
:
print
(
r
'
\coordinate[right of=%s, xshift=%s%s] (right);
'
%
(
nodes
[
-
1
].
identifier
,
b
.
factor
*
self
.
sep
,
self
.
sep_unit
),
file
=
file
)
# Base line between last_node and e.
print
(
r
'
\draw[%s] (%s) -- (right);
'
%
(
b
.
style
,
nodes
[
-
1
].
identifier
),
file
=
file
)
print
(
e
.
tikz
(
contour
.
elements
[
j
-
1
],
contour
.
elements
[
j
+
1
]),
file
=
file
)
except
:
pass
if
type
(
e
)
==
BaseLine
:
try
:
assert
not
self
.
interruptions
[
i
].
isKeldysh
()
print
(
e
.
tikz
(
contour
.
elements
[
-
2
],
self
.
interruptions
[
i
]),
file
=
file
)
except
:
try
:
print
(
r
'
\coordinate[right of=%s, xshift=%g%s] (right%d);
'
%
(
contour
.
elements
[
-
2
].
identifier
,
e
.
factor
*
self
.
sep
,
self
.
sep_unit
,
i
),
file
=
file
)
print
(
r
'
\draw[%s] (%s) -- (right%d);
'
%
(
e
.
style
,
contour
.
elements
[
-
2
].
identifier
,
i
),
file
=
file
)
except
:
pass
try
:
if
self
.
interruptions
[
i
].
isKeldysh
():
# Draw connection of the contours.
if
self
.
interruptions
[
i
].
keldysh_direction
==
'
right
'
:
self
.
interruptions
[
i
].
tikz
(
previous
=
last_node
)
string
=
self
.
interruptions
[
i
].
tikzKeldyshConnect
(
last_node
)
else
:
else
:
# Base line between two nodes.
string
=
self
.
interruptions
[
i
].
tikzKeldyshConnect
(
self
.
interruptions
[
i
-
1
])
print
(
r
'
\draw[%s] (%s) -- (%s);
'
%
(
b
.
style
,
nodes
[
i
].
identifier
,
nodes
[
i
+
1
].
identifier
),
file
=
file
)
if
string
:
print
(
string
,
file
=
file
)
except
:
pass
# Draw all contractions.
# Draw all contractions.
for
c
in
self
.
contractions
:
for
c
in
self
.
contractions
:
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment