home

Regulated and Unregulated Propagators

Compare the loop structures before and after inserting a scale-dependent regulator. The compact view introduces the topology; the detailed views show momentum and field indices.


Regulated and Unregulated Propagators

Download

PNG PDF SVG

Code

regulated-and-unregulated-propagators.typ (325 lines)
#import "@preview/cetz:0.5.3": canvas, draw
#import draw: circle, content, line, mark, translate
#let label-size = 12pt
#let paragraph-size = 14pt
#let heading-size = 16pt

#let card(title, body, caption) = grid(
  columns: (100%,),
  block(
    width: 100%,
    inset: 12pt,
    radius: 8pt,
    fill: rgb("#cdd3da"),
    breakable: false,
  )[
    #text(size: heading-size, weight: "bold", title)
    #v(8pt)
    // Measure unconstrained artwork before scaling, including content wider than its card.
    #layout(size => {
      let artwork = text(size: label-size, body)
      std.scale(size.width / measure(artwork).width * 100%, reflow: true, artwork)
    })
    #v(7pt)
    #text(size: paragraph-size, caption)
  ],
)

#let takeaway(body) = block(
  width: 100%,
  inset: 12pt,
  radius: 6pt,
  fill: rgb("#c6d8d2"),
  breakable: false,
  text(size: paragraph-size, body),
)

#set page(width: 780pt, height: auto, margin: 22pt, fill: none)
#set text(font: "Avenir Next", size: paragraph-size, fill: rgb("#19324f"))
#set par(leading: 0.55em)

// Diagonal hatching marking a propagator or vertex as dressed rather than bare.
#let hatched = tiling(size: (.1cm, .1cm))[
  #place(std.rect(width: 100%, height: 100%, fill: rgb("#cdd3da"), stroke: none))
  #place(std.line(start: (0%, 100%), end: (100%, 0%), stroke: 0.4pt))
]

// Hairline tying a label to whatever it names: pole callouts, semi-axis leaders,
// off-diagram vertex captions.
#let leader = (paint: rgb("#78828C"), thickness: 0.5pt)

// Dressed vertices use hatching; trailing options position their labels.
#let dressed_vertex(pos, label, offset, radius: 0.25, stroke: 0.5pt, ..style) = {
  circle(pos, radius: radius, fill: hatched, stroke: stroke)
  content((rel: offset, to: pos), $#label$, ..style)
}

// Momentum labels and arrowheads around the loop; fractions set their positions.
#let loop-momenta(radius, momenta, symbol: "stealth", sweep: 1deg, angle: 60deg, fill: black) = {
  for (idx, fraction) in momenta {
    let turn = fraction * 360deg
    // trail the label a few degrees behind its arrowhead
    let lag = turn - 3deg
    let offset = ((0.75 * radius) * calc.cos(lag), (0.75 * radius) * calc.sin(lag))
    content((rel: offset, to: "loop"), $p_#idx$, size: label-size)
    mark(
      (name: "loop", anchor: turn),
      (name: "loop", anchor: turn + sweep),
      symbol: symbol,
      width: .25,
      length: .15,
      stroke: .7pt,
      scale: .7,
      angle: angle,
      fill: fill,
    )
  }
}

// === 1  Recognize the two topologies ===
#let figure-0 = [

  #let radius = 1
  #let vertex = dressed_vertex.with(radius: 0.25 * radius, stroke: auto, anchor: "south")

  #canvas(length: 2.63cm, {
    // Gamma^(3) loop: two dressed three-point vertices on the external legs
    circle((0, 0), radius: radius, stroke: 1pt)
    line((-2 * radius, 0), (-radius, 0), stroke: 1pt)
    line((radius, 0), (2 * radius, 0), stroke: 1pt)
    vertex((-radius, 0), $Gamma_k^((3))$, (-0.3, 0.3))
    vertex((radius, 0), $Gamma_k^((3))$, (0.3, 0.3))

    content((3 * radius, 0), $-$)

    // Gamma^(4) tadpole: one dressed four-point vertex on a single external line
    translate((5 * radius, 0))
    circle((0, 0), radius: radius, stroke: 1pt)
    line((-2 * radius, -radius), (2 * radius, -radius), stroke: 1pt)
    vertex((0, -radius), $Gamma_k^((4))$, (0, 0.35))
  })
]

// === 2  Resolve the internal labels ===
#let figure-1 = [

  #let momentum-arrow = (
    mark: (end: "stealth", fill: black, scale: .5),
    stroke: (thickness: 0.75pt),
  )

  #let radius = 1.25
  #let med-rad = 0.175 * radius
  #let vertex = dressed_vertex.with(radius: 0.15 * radius)
  // Momentum arrow of length 0.6*radius, drawn just above height `y`.
  #let momentum(idx, x-center, y) = {
    let half = 0.3 * radius
    let name = "q" + str(idx)
    line((x-center - half, y + 0.15), (rel: (2 * half, 0)), ..momentum-arrow, name: name)
    content((rel: (0, 0.3), to: name + ".mid"), $q_#idx$)
  }

  // Gamma^(3) loop closed by two dressed propagators (top and bottom), then the Gamma^(4) tadpole
  #stack(
    dir: ltr,
    spacing: 12pt,
    canvas(length: 1.61cm, {
      circle((0, 0), radius: radius, stroke: 1pt, name: "loop")
      loop-momenta(radius, ((1, 0.125), (2, 0.375), (3, 0.625), (4, 0.875)))

      vertex((0, radius), $G_(k,i j)(p_1,p_2)$, (0, 0.2), anchor: "south")
      vertex((0, -radius), $G_(k,k l)(p_3,p_4)$, (0, -0.3), anchor: "north")

      line((-2 * radius, 0), (-radius, 0), stroke: 1pt, name: "left-external")
      line((radius, 0), (2 * radius, 0), stroke: 1pt, name: "right-external")
      content("left-external.start", $phi_a$, anchor: "east", padding: 0.1)
      content("right-external.end", $phi_b$, anchor: "west", padding: 0.1)
      momentum(1, -1.6 * radius, 0)
      momentum(2, 1.6 * radius, 0)

      for (name, side, label) in (
        ("gamma-left", -1, $Gamma_(k,a j k)^((3))(q_1,p_2,-p_3)$),
        ("gamma-right", 1, $Gamma_(k,b l i)^((3))(-q_2,p_4,-p_1)$),
      ) {
        content((side * 2.1 * radius, radius), label, name: name)
        line(name, (side * radius, 0), stroke: leader)
        circle((side * radius, 0), radius: med-rad, fill: hatched, stroke: 0.5pt)
      }
    }),
    canvas(length: 1.61cm, {
      circle((0, 0), radius: radius, stroke: 1pt, name: "loop")
      loop-momenta(radius, ((1, 0), (2, 0.5)))

      vertex((0, radius), $G_(k,i j)(p_1,p_2)$, (0, 0.2), anchor: "south")

      line((-2 * radius, -radius), (2 * radius, -radius), stroke: 1pt, name: "external")
      content((rel: (-0.1, 0), to: "external.start"), $phi_a$, anchor: "east")
      content((rel: (0.1, 0), to: "external.end"), $phi_b$, anchor: "west")
      momentum(1, -1.6 * radius, -radius)
      momentum(2, 1.6 * radius, -radius)

      vertex(
        (0, -radius),
        $Gamma_(k,a b j i)^((4))(q_1,-q_2,p_2,-p_1)$,
        (0, -0.3),
        radius: med-rad,
        anchor: "north",
      )
    }),
  )
]

// === 3  Insert the changing cutoff ===
#let figure-2 = [

  // Regulator insertion: a circled cross on an opaque gray disc, labeled on its outer `side`.
  #let cross(pos, label, side) = {
    content(
      pos,
      text(size: 16pt)[$times.o$],
      stroke: none,
      fill: rgb("#cdd3da"),
      frame: "circle",
      padding: -2.5pt,
      name: "cross",
    )
    let opposite = if side == "north" { "south" } else { "north" }
    content("cross." + side, $#label$, anchor: opposite, padding: 3pt)
  }

  #let radius = 1.25
  #let med-rad = 0.13 * radius
  #let vertex = dressed_vertex.with(radius: 0.1 * radius)
  #let q-arrow = (
    mark: (end: "barbed", fill: black, scale: .5, width: .25, length: .2, angle: 60deg),
    stroke: .5pt,
  )

  #let at(pos) = (rel: pos, to: "loop")
  // Point on the loop at `turn` around it, measured counter-clockwise from 3 o'clock.
  #let on-loop(turn) = at((radius * calc.cos(turn), radius * calc.sin(turn)))

  #let barbed-momenta = loop-momenta.with(
    radius,
    symbol: "barbed",
    sweep: 0.1deg,
    angle: 70deg,
    fill: none,
  )

  // Straight external legs meeting the loop at 9 and 3 o'clock, each capped by a vertex.
  #let side-legs() = {
    for (name, side, turn, label) in (
      ("left-external", -1, 180deg, $phi_a$),
      ("right-external", 1, 0deg, $phi_b$),
    ) {
      line(on-loop(turn), at((side * 2 * radius, 0)), stroke: 1pt, name: name)
      content((rel: (side * 0.2, -0.3), to: name + ".mid"), label)
      circle(
        at((side * radius, 0)),
        radius: med-rad,
        fill: hatched,
        stroke: 0.5pt,
        name: "vertex-" + name,
      )
    }
  }

  // Incoming q_1 and outgoing q_2, both pointing right, at height `y`.
  #let external-momenta(inner, outer, y: 0.15) = {
    for (idx, x-start, x-end) in ((1, -outer, -inner), (2, inner, outer)) {
      let name = "q" + str(idx) + "-arrow"
      line(at((x-start, y)), at((x-end, y)), ..q-arrow, name: name)
      content(name + ".mid", $q_#idx$, anchor: "south", padding: (0, 0, 2pt))
    }
  }

  // Off-diagram Gamma^(3) label tied to the vertex it names by a hairline.
  #let gamma-callout(pos, label, target, ..style) = {
    content(pos, label, ..style, name: "callout")
    line("callout", target, stroke: leader)
  }

  #stack(
    dir: ltr,
    spacing: 12pt,
    canvas(length: 1.02cm, {
      circle((0, 0), radius: radius, stroke: 1pt, name: "loop")
      barbed-momenta(((6, 0.0625), (1, 0.1875), (2, 0.3125), (3, 0.4375), (4, 0.625), (5, 0.875)))

      cross(at((0, radius)), $partial_k R_(k,i j) (p_1,p_2)$, "north")
      vertex(on-loop(135deg), $G_(k,j k)(p_2,p_3)$, (-1.2, 0.3))
      vertex(on-loop(45deg), $G_(k,n i)(p_6,p_1)$, (1.2, 0.3))
      vertex(at((0, -radius)), $G_(k,l m) (p_4,p_5)$, (0, -.8))

      side-legs()
      external-momenta(1.4, 2.3)
      gamma-callout(at((-2, -1.5)), $Gamma_(k,a k l)^((3))(q_1,p_3,-p_4)$, "vertex-left-external")
      gamma-callout(
        at((2.3, -1.5)),
        $Gamma_(k,b m n)^((3))(-q_2,p_5,-p_6)$,
        "vertex-right-external",
      )
    }),
    canvas(length: 1.02cm, {
      circle((0, 0), radius: radius, stroke: 1pt, name: "loop")
      barbed-momenta(((6, 0.125), (3, 0.375), (4, 0.5625), (1, 0.6875), (2, 0.8125), (5, 0.9375)))

      cross(at((0, -radius)), $partial_k R_(k,i j)(p_1,p_2)$, "south")
      vertex(on-loop(-45deg), $G_(k,j m)(p_2,p_5)$, (1.2, -0.3))
      vertex(on-loop(225deg), $G_(k,l i)(p_4,p_1)$, (-1.2, -0.3))
      vertex(at((0, radius)), $G_(k,n k)(p_6,p_3)$, (0, 0.5), name: "top-label")

      side-legs()
      external-momenta(1.6, 2.4)
      // flank the top propagator label so neither callout reaches the loop
      for (side, anchor, label) in (
        ("west", "east", $Gamma_(k,a k l)^((3))(q_1,p_3,-p_4)$),
        ("east", "west", $Gamma_(k,b m n)^((3))(-q_2,p_5,-p_6)$),
      ) {
        let target = "vertex-" + if side == "west" { "left" } else { "right" } + "-external"
        gamma-callout("top-label." + side, label, target, anchor: anchor, padding: 0.3)
      }
    }),
    canvas(length: 1.02cm, {
      circle((0, 0), radius: radius, stroke: 1pt, name: "loop")
      barbed-momenta(((1, 0.125), (2, 0.375), (3, 0.625), (4, 0.875)))

      cross(at((0, radius)), $partial_k R_(k,i j)(p_1,p_2)$, "north")
      vertex(at((-radius, 0)), $G_(k,j k)(p_2,p_3)$, (-0.2, 0), anchor: "east")
      vertex(at((radius, 0)), $G_(k,l i)(p_4,p_1)$, (0.2, 0), anchor: "west")

      line(at((-2.2 * radius, -radius)), at((2.2 * radius, -radius)), stroke: 1pt)
      circle(at((0, -radius)), radius: med-rad, fill: hatched, stroke: 0.5pt)
      content(at((0, -2)), $Gamma_(k,a b k l)^((4))(q_1,-q_2,p_3,-p_4)$)
      content(at((-2.5, -1.5)), $phi_a$)
      content(at((2.5, -1.5)), $phi_b$)

      external-momenta(1.3, 2.3, y: -radius + 0.15)
    }),
  )
]

Compare the loop structures before and after inserting a scale-dependent regulator. The compact view introduces the topology; the detailed views show momentum and field indices.
#v(14pt)
#stack(
  dir: ttb,
  spacing: 12pt,
  card(
    [1  Recognize the two topologies],
    figure-0,
    [A loop with two three-point vertices and a tadpole with one four-point vertex. Signs and symmetry factors belong to the defining equation and conventions.],
  ),
  card(
    [2  Resolve the internal labels],
    figure-1,
    [The same building blocks with explicit external legs and loop momenta. Without a regulator, integration is not restricted by the running cutoff.],
  ),
  card(
    [3  Insert the changing cutoff],
    figure-2,
    [Each circled cross is $partial_k R_k$. Different insertion positions contribute to the scale derivative of the two-point function; these sketches show the terms, not their prefactors.],
  ),
)
#v(12pt)
#takeaway[*The cross makes a flow diagram scale selective.* With a suitable regulator, low-momentum modes are suppressed and the derivative weights the modes being integrated out near scale $k$. $G_k$ is a full propagator; $Gamma_k^((n))$ couples $n$ field legs. Hatched discs mark these dressed propagators and vertices.]