Virasoro algebra
Virasoro algebra is the central extension of a Lie algebra with wide applications in the two-dimensional conformal field theory. Its generators \(L_n, n \in \mathbb{Z}\) satisfy commutation relations
where \(c\) is the central charge commuting with all generators. It was shown in [FNZ88] that the Virasoro algebra can be constructed out of just two generators \(L_3\) and \(L_{-2}\) using the following recurrence relations,
In the example below, we show how to implement the Virasoro algebra in libcommute’s framework and use it to verify the recurrence relations stated above.
1#include <iostream>
2#include <memory>
3#include <tuple>
4
5#include <libcommute/libcommute.hpp>
6
7namespace libcommute {
8
9// Define a new generator type by deriving from the abstract base class
10// 'libcommute::generator<IndexTypes...>'. Generators of the Virasoro algebra
11// L_n carry one integer index 'n'.
12// Canonical order of generators in a monomial L_n * L_m * L_k * ... is such
13// that n < m < k < ...
14class generator_virasoro : public generator<int> {
15
16 using base = generator<int>;
17 using linear_function_t = typename base::linear_function_t;
18
19 // For the sake of simplicity, we fix the central charge once and for all.
20 static constexpr double central_charge = 2.0;
21
22public:
23 // This function must return a unique algebra ID shared by all generators
24 // of a particular algebra.
25 int algebra_id() const override {
26 // Use the lowest algebra ID available to user-defined algebras
27 return min_user_defined_algebra_id;
28 }
29
30 // Construct generator with a given index 'n'
31 explicit generator_virasoro(int n) : base(n) {}
32 // Standard constructors, assignments and destructor
33 generator_virasoro(generator_virasoro const&) = default;
34 generator_virasoro(generator_virasoro&&) noexcept = default;
35 generator_virasoro& operator=(generator_virasoro const&) = default;
36 generator_virasoro& operator=(generator_virasoro&&) noexcept = default;
37 ~generator_virasoro() override = default;
38
39 // Virtual copy-constructor: Make a smart pointer managing
40 // a copy of this generator
41 std::unique_ptr<base> clone() const override {
42 return make_unique<generator_virasoro>(*this);
43 }
44
45 // Given a product L_m * L_n with m > n, transform it to the canonically
46 // ordered form L_n * L_m plus some linear function of generators.
47 // For the Virasoro algebra the transformation is
48 //
49 // L_m * L_n -> L_n * L_m + (m-n)*L_{m+n} + c(m^3 - m)\delta(m,-n)
50 //
51 // L_m will be passed to swap_with() as *this, i.e. L_m.swap_with(L_n, f).
52 double swap_with(base const& L_n, linear_function_t& f) const override {
53 // Ensure that L_m > L_n, or equivalently m > n.
54 assert(*this > L_n);
55
56 auto const& L_n_ = dynamic_cast<generator_virasoro const&>(L_n);
57
58 // Extract indices from L_m and L_n
59 int m = std::get<0>(base::indices());
60 int n = std::get<0>(L_n_.indices());
61
62 // Write linear terms of the transformed expressions into 'f'
63 f.set(m == -n ? (central_charge * (m * m * m - m)) : 0, // Constant term
64 make_unique<generator_virasoro>(m + n), // L_{m+n}
65 m - n // Coefficient in front of L_{m+n}
66 );
67
68 // Return coefficient in front of L_n * L_m in the transformed expression
69 return 1;
70 }
71
72 // Given a product L_m * L_n with m <= n, optionally transform it to
73 // some linear function of generators. For the Virasoro algebra such a
74 // transformation exists for L_m = L_n,
75 //
76 // L_m * L_n -> 0
77 //
78 // L_m will be passed to simplify_prod() as *this,
79 // i.e. L_m.simplify_prod(L_n, f).
80 bool simplify_prod(base const& L_n, linear_function_t& f) const override {
81 // Ensure that L_m <= L_n, or equivalently m <= n.
82 assert(!(*this > L_n));
83
84 if(*this == L_n) {
85 // The transformed product is identically zero
86 f.set(0);
87 return true;
88 } else
89 return false; // No suitable transformation can be applied
90 }
91
92 // Hermitian conjugate: (L_n)^\dagger = L_{-n}
93 void conj(linear_function_t& f) const override {
94 int conj_n = -std::get<0>(base::indices());
95 f.set(0, make_unique<generator_virasoro>(conj_n), 1);
96 }
97
98 // Print L_n to stream
99 std::ostream& print(std::ostream& os) const override {
100 int n = std::get<0>(base::indices());
101 return os << "L(" << n << ")";
102 }
103};
104
105// Convenience factory function to create expressions made of one
106// monomial L_n.
107expression<double, int> L(int n) {
108 using ret_t = expression<double, int>;
109 return ret_t(1.0, ret_t::monomial_t(generator_virasoro(n)));
110}
111
112} // namespace libcommute
113
114using namespace libcommute;
115
116int main() {
117
118 // Check that L(0) is Hermitian and (L_n)^\dagger = L_{-n}
119 std::cout << "conj(L(0)) = " << conj(L(0)) << '\n';
120 std::cout << "conj(L(1)) = " << conj(L(1)) << '\n';
121
122 // Check that L(n)^2 = 0 for a few n
123 std::cout << "L(0) * L(0) = " << L(0) * L(0) << '\n';
124 std::cout << "L(1) * L(1) = " << L(1) * L(1) << '\n';
125 std::cout << "L(-1) * L(-1) = " << L(-1) * L(-1) << '\n';
126
127 // Check recurrence relations from Eq. (5)
128 std::cout << "L_1 - (1/5)[L_3, L_{-2}] = "
129 << (L(1) - (1.0 / 5) * (L(3) * L(-2) - L(-2) * L(3))) << '\n';
130 std::cout << "L_{-1} - (1/3)[L_1, L_{-2}] = "
131 << (L(-1) - (1.0 / 3) * (L(1) * L(-2) - L(-2) * L(1))) << '\n';
132 std::cout << "L_2 - (1/4)[L_3, L_{-1}] = "
133 << (L(2) - (1.0 / 4) * (L(3) * L(-1) - L(-1) * L(3))) << '\n';
134 std::cout << "L_0 - (1/2)[L_1, L_{-1}] = "
135 << (L(0) - (1.0 / 2) * (L(1) * L(-1) - L(-1) * L(1))) << '\n';
136
137 // Check recurrence relation Eq. (6) for some higher positive n
138 for(int n = 3; n < 10; ++n) {
139 std::cout << "L_" << (n + 1) << " - (1/" << (n - 1) << ")"
140 << "[L_" << n << ", L_1] = "
141 << (L(n + 1) - (1.0 / (n - 1)) * (L(n) * L(1) - L(1) * L(n)))
142 << '\n';
143 }
144 // Check recurrence relation Eq. (7) for some higher negative n
145 for(int n = 2; n < 10; ++n) {
146 std::cout << "L_" << (-n - 1) << " - (1/(" << (1 - n) << "))"
147 << "[L_" << -n << ", L_{-1}] = "
148 << (L(-n - 1) - (1.0 / (1 - n)) * (L(-n) * L(-1) - L(-1) * L(-n)))
149 << '\n';
150 }
151
152 return 0;
153}
“A presentation for the Virasoro and super-Virasoro algebras”, D. B. Fairlie, J. Nuyts and C. K. Zachos , Commun. Math. Phys. 117, pp. 595–614 (1988), https://doi.org/10.1007/BF01218387