Skip to content

Commit 1a1d4b8

Browse files
committed
Add "pfaffian" for finding Pfaffians of a skew symmetric matrices
We already have "pfaffians" for returning an ideal containing all the sub-Pfaffians of a particular size, but we may just want the Pfaffian itself as a number or polynomial, cf. "minors" v. "det".
1 parent a4b4c80 commit 1a1d4b8

File tree

13 files changed

+84
-3
lines changed

13 files changed

+84
-3
lines changed

M2/Macaulay2/d/interface.dd

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,6 +2262,13 @@ export rawPfaffians(e:Expr):Expr := (
22622262
);
22632263
setupfun("rawPfaffians",rawPfaffians);
22642264

2265+
export rawPfaffian(e:Expr):Expr := (
2266+
when e
2267+
is M:RawMatrixCell do toExpr(Ccode(RawRingElementOrNull,
2268+
"IM2_Matrix_pfaffian(", M.p, ")"))
2269+
else WrongArgMatrix());
2270+
setupfun("rawPfaffian", rawPfaffian);
2271+
22652272
export rawTensor(e:Expr):Expr := (
22662273
when e is s:Sequence do
22672274
when s.0

M2/Macaulay2/e/interface/matrix.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,11 @@ const Matrix /* or null */ *IM2_Matrix_pfaffians(int p, const Matrix *M)
556556
return M->pfaffians(p);
557557
}
558558

559+
const RingElement /* or null */ *IM2_Matrix_pfaffian(const Matrix *M)
560+
{
561+
return RingElement::make_raw(M->get_ring(), M->pfaffian());
562+
}
563+
559564
const Matrix /* or null */ *IM2_Matrix_diff(const Matrix *M, const Matrix *N)
560565
{
561566
return M->diff(N, 1);

M2/Macaulay2/e/interface/matrix.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ const Matrix /* or null */ *IM2_Matrix_pfaffians(
241241
int p,
242242
const Matrix *M); /* drg: connected rawPfaffians*/
243243

244+
const RingElement /* or null */ *IM2_Matrix_pfaffian(
245+
const Matrix *M);
246+
244247
const Matrix *rawMatrixCompress(
245248
const Matrix *M); /* connected rawMatrixCompress */
246249

M2/Macaulay2/e/matrix.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,10 @@ class Matrix : public EngineObject
165165
M2_arrayintOrNull first_col // possibly NULL
166166
) const;
167167

168-
Matrix *pfaffians(int p) const; // in pfaff.cpp
168+
// in pfaff.cpp
169+
Matrix *pfaffians(int p) const;
170+
ring_elem pfaffian() const;
171+
169172
static Matrix *wedge_product(int p, int q, const FreeModule *F);
170173
// static Matrix wedge_dual(int p, const FreeModule *F);
171174

M2/Macaulay2/e/pfaff.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ int PfaffianComputation::step()
3030
{
3131
if (done) return COMP_DONE;
3232

33-
ring_elem r = calc_pfaff(row_set, p);
33+
ring_elem r = calc_pfaff();
3434
if (!R->is_zero(r))
3535
pfaffs.append(R->make_vec(0, r));
3636
else
@@ -54,6 +54,11 @@ int PfaffianComputation::calc(int nsteps)
5454
}
5555
}
5656

57+
ring_elem PfaffianComputation::calc_pfaff(void)
58+
{
59+
return calc_pfaff(row_set, p);
60+
}
61+
5762
ring_elem PfaffianComputation::calc_pfaff(size_t *r, int p2)
5863
// Compute the pfaffian of the (skew symmetric)
5964
// minor with rows and columns r[0]..r[p2-1].
@@ -105,6 +110,13 @@ Matrix *Matrix::pfaffians(int p) const
105110
return d.pfaffians();
106111
}
107112

113+
ring_elem Matrix::pfaffian() const
114+
{
115+
PfaffianComputation d {this, n_cols()};
116+
117+
return d.calc_pfaff();
118+
}
119+
108120
// Local Variables:
109121
// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
110122
// indent-tabs-mode: nil

M2/Macaulay2/e/pfaff.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class PfaffianComputation : public our_new_delete
4242

4343
Matrix *pfaffians() { return pfaffs.to_matrix(); }
4444
const Ring *get_ring() const { return R; }
45+
ring_elem calc_pfaff(void);
4546
};
4647

4748
#endif

M2/Macaulay2/m2/exports.m2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,7 @@ export {
10001000
"peek'",
10011001
"permanents",
10021002
"permutations",
1003+
"pfaffian",
10031004
"pfaffians",
10041005
"pi",
10051006
"pivots",

M2/Macaulay2/m2/multilin.m2

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,16 @@ pfaffians = method(TypicalValue => Ideal)
157157
pfaffians(ZZ, Matrix) := (j, m) -> (
158158
ideal(map(ring m, rawPfaffians(j,raw m))))
159159

160+
pfaffian = method()
161+
pfaffian Matrix := M -> (
162+
if (
163+
numRows M != numColumns M or
164+
not zero(M + transpose M))
165+
then error "expected a skew symmetric matrix";
166+
if odd numRows M then 0_(ring M)
167+
else if numRows M == 0 then 1_(ring M)
168+
else promote(rawPfaffian raw M, ring M))
169+
160170
-----------------------------------------------------------------------------
161171
-- trace and determinant
162172
-----------------------------------------------------------------------------

M2/Macaulay2/packages/Macaulay2Doc/functions.m2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ load "./functions/pdim-doc.m2"
203203
load "./functions/peek-doc.m2"
204204
load "./functions/permanents-doc.m2"
205205
load "./functions/permutations-doc.m2"
206+
load "./functions/pfaffian-doc.m2"
206207
load "./functions/pfaffians-doc.m2"
207208
load "./functions/pivots-doc.m2"
208209
load "./functions/poincare-doc.m2"
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
doc ///
2+
Key
3+
pfaffian
4+
(pfaffian, Matrix)
5+
Headline
6+
Pfaffian of a skew-symmetric matrix
7+
Usage
8+
pfaffian M
9+
Inputs
10+
M:Matrix -- must be skew-symmetric
11+
Outputs
12+
:{Number,RingElement} -- the Pfaffian of @VAR "M"@
13+
Description
14+
Text
15+
The @wikipedia "Pfaffian"@ of a $2n\times 2n$ skew-symmetric matrix
16+
$M=(m_{ij})$ is
17+
$$\frac{1}{2^nn!}\sum_{\sigma\in S_{2n}}\operatorname{sgn}(\sigma)\prod_{i=1}^nm_{\sigma(2i-1),\sigma(2i)},$$
18+
where $S_n$ is the symmetric group on $2n$ elements.
19+
Example
20+
M = matrix {{0, 1, 2, 3}, {-1, 0, 4, 5}, {-2, -4, 0, 6}, {-3, -5, -6, 0}}
21+
pfaffian M
22+
Text
23+
The square of the Pfaffian is the determinant.
24+
Example
25+
determinant M
26+
Text
27+
Skew-symmetric matrices with an odd number of rows and columns have
28+
Pfaffian zero.
29+
Example
30+
M = matrix {{0, 1, 2}, {-1, 0, 3}, {-2, -3, 0}}
31+
pfaffian M
32+
SeeAlso
33+
determinant
34+
pfaffians
35+
///

0 commit comments

Comments
 (0)