1 | initial version |
Using matrices over QQ[i]
instead of CC
or CDF
will avoid rounding errors.
2 | No.2 Revision |
Using matrices over GaussianIntegers()
or ZZ[i]
or QQ[i]
or QQbar
instead of CC
or CDF
will avoid rounding errors.
Communicating a 52 x 52 matrix with entries in {0, 1, -1, i, -i} is doable.
You can encode the matrix and provide decoding instructions rather than the matrix itself.
One possible encoding, since the entries can only take 5 values, take them as 5-ary digits; then each row can be thought of as the 5-ary expansion of a number. If we agree on the digits and communicate the numbers, we're good.
Here is a random matrix a
with entries in {0, 1, -1, i, -i}:
sage: G = GaussianIntegers()
sage: U = [0, 1, -1, i, -i]
sage: a = matrix(G, 52, lambda i, j: U[randint(0, 4)])
Encoded matrix:
sage: b = [Integer(tuple(U.index(e) for e in row), 5) for row in a]
sage: print(b)
[1986835196674783292709127771671427698, 372532889760445898415871372893604877,
29903254311383361818758881193795318, 1358695302115484662298806740046547384,
1537321601024823802437657316988965568, 807200500103255107975400681439180354,
567350510853383980331713019521919561, 1502850803304703506587108729499355006,
846884730762028905888265726139310683, 137381915837271267181515478275643286,
522105367460276163750943030646864364, 1062521690576328608603843582516522599,
899547582492594668160772320652245190, 767732247768012897653127687752209191,
629354811960707798077793065391805161, 922202162939977177914455168534168765,
1729869497057901779087386639626774141, 1868018985439944039499425518652161649,
1296299082686624643142119402841062894, 1064799841987832209268578137251968874,
2155066789175869415783929309121456698, 267366791364966820259349410583047599,
1632002494019334195780113340724191796, 2192661273536615612340019587291366905,
1762917404578120599684457836032844498, 228986171419406644876547615831863389,
2101920423365829833128536344495944345, 660985714605962040665526677335410210,
873334831095240711598788236281716427, 1744121894438415469560277438117935725,
2210059965689974187926035573546483126, 1594508474721458635473949546648185838,
518211385383214049244941993118895991, 231206763245123017363282654207827645,
1748059359372987512622900717899928645, 259988738192311572545249238464600548,
2007721547194093983826996655201647232, 1240843285105582949996674635390136465,
1736982326629685244276013105887136315, 435682393610221223713098672542297123,
66566788503415822985489945441756435, 1141561970732274264554486688206105649,
2044822779971527183978088623745613537, 17299608296692077102235770236630252,
780853597789891512314851615527578148, 427428566224687826328803693567479441,
1922351158930802787176924223394683886, 2104373328835002410314401979576425296,
1317300586469460326137557530572476230, 1736284365530465805899187629996562866,
2132757211837100962505268985637520292, 147031314086172436786678135727403627]
To decode:
sage: aa = matrix(G, 52, [[U[d] for d in r.digits(5, padto=52)] for r in b])
sage: aa == a
True
Here is a function that takes a matrix as an argument, and returns "short enough code" to recreate that matrix.
def matrix_code(a):
r"""
Return code for a matrix with entries in {0, 1, -1, i, -i}.
EXAMPLE::
sage: G = GaussianIntegers()
sage: U = [0, 1, -1, i, -i]
sage: a = matrix(G, 52, lambda i, j: U[randint(0, 4)])
sage: matrix_code(a)
...
"""
G = GaussianIntegers()
U = [0, 1, -1, i, -i]
m = a.nrows()
n = a.ncols()
b = [Integer(tuple(U.index(e) for e in row), 5) for row in a]
print(f"""
G = GaussianIntegers()
U = [0, 1, -1, i, -i]
b = {b}
a = matrix(G, {m}, {n}, [[U[d] for d in r.digits(5, padto={n})] for r in b])
""")
Run it on your matrix. Edit your question, pasting the output. Then we can all play with the same matrix.
3 | No.3 Revision |
Using
Why is this happening and is there another way I can avoid large rounding errors when taking the inverse?
This is happening because CC
and CDF
use floating-point numbers,
and computations are thus inexact and subject to rounding errors.
Instead of working with CC
or CDF
, one could
use
GaussianIntegers()
or ZZ[i]
or QQ[i]
or QQbar
use matrices over CBF
("complex ball field")
for floating-point computations with rigorous error bounds
ofI'm not really sure how to provide an example
CC
or CDF
will avoid rounding errors.Communicating a 52 x 52 matrix with entries in {0, 1, -1, i, -i} is doable.
You can encode the matrix and provide decoding instructions rather than the matrix itself.
One possible encoding, since the entries can only take 5 values, take them as 5-ary digits; then each row can be thought of as the 5-ary expansion of a number. If we agree on the digits and communicate the numbers, we're good.
Here is a random matrix a
with entries in {0, 1, -1, i, -i}:
sage: G = GaussianIntegers()
sage: U = [0, 1, -1, i, -i]
sage: a = matrix(G, 52, lambda i, j: U[randint(0, 4)])
Encoded matrix:
sage: b = [Integer(tuple(U.index(e) for e in row), 5) for row in a]
sage: print(b)
[1986835196674783292709127771671427698, 372532889760445898415871372893604877,
29903254311383361818758881193795318, 1358695302115484662298806740046547384,
1537321601024823802437657316988965568, 807200500103255107975400681439180354,
567350510853383980331713019521919561, 1502850803304703506587108729499355006,
846884730762028905888265726139310683, 137381915837271267181515478275643286,
522105367460276163750943030646864364, 1062521690576328608603843582516522599,
899547582492594668160772320652245190, 767732247768012897653127687752209191,
629354811960707798077793065391805161, 922202162939977177914455168534168765,
1729869497057901779087386639626774141, 1868018985439944039499425518652161649,
1296299082686624643142119402841062894, 1064799841987832209268578137251968874,
2155066789175869415783929309121456698, 267366791364966820259349410583047599,
1632002494019334195780113340724191796, 2192661273536615612340019587291366905,
1762917404578120599684457836032844498, 228986171419406644876547615831863389,
2101920423365829833128536344495944345, 660985714605962040665526677335410210,
873334831095240711598788236281716427, 1744121894438415469560277438117935725,
2210059965689974187926035573546483126, 1594508474721458635473949546648185838,
518211385383214049244941993118895991, 231206763245123017363282654207827645,
1748059359372987512622900717899928645, 259988738192311572545249238464600548,
2007721547194093983826996655201647232, 1240843285105582949996674635390136465,
1736982326629685244276013105887136315, 435682393610221223713098672542297123,
66566788503415822985489945441756435, 1141561970732274264554486688206105649,
2044822779971527183978088623745613537, 17299608296692077102235770236630252,
780853597789891512314851615527578148, 427428566224687826328803693567479441,
1922351158930802787176924223394683886, 2104373328835002410314401979576425296,
1317300586469460326137557530572476230, 1736284365530465805899187629996562866,
2132757211837100962505268985637520292, 147031314086172436786678135727403627]
To decode:
sage: aa = matrix(G, 52, [[U[d] for d in r.digits(5, padto=52)] for r in b])
sage: aa == a
True
Here is a function that takes a matrix as an argument, and returns "short enough code" to recreate that matrix.
def matrix_code(a):
r"""
Return code for a matrix with entries in {0, 1, -1, i, -i}.
EXAMPLE::
sage: G = GaussianIntegers()
sage: U = [0, 1, -1, i, -i]
sage: a = matrix(G, 52, lambda i, j: U[randint(0, 4)])
sage: matrix_code(a)
...
"""
G = GaussianIntegers()
U = [0, 1, -1, i, -i]
m = a.nrows()
n = a.ncols()
b = [Integer(tuple(U.index(e) for e in row), 5) for row in a]
print(f"""
G = GaussianIntegers()
U = [0, 1, -1, i, -i]
b = {b}
a = matrix(G, {m}, {n}, [[U[d] for d in r.digits(5, padto={n})] for r in b])
""")
Run it on your matrix. Edit your question, pasting the output. Then we can all play with the same matrix.
4 | No.4 Revision |
Why is this happening and is there another way I can avoid large rounding errors when taking the inverse?
This is happening because CC
and CDF
use floating-point numbers,
and computations are thus inexact and subject to rounding errors.
Instead of working with CC
or CDF
, one could
use matrices over GaussianIntegers()
or ZZ[i]
or QQ[i]
or QQbar
for exact computations
use matrices over CBF
("complex ball field")
for floating-point computations with rigorous error bounds
I'm not really sure how to provide an example of this error occurring since the smallest example of the array I am working with is (52x52).
Communicating a 52 x 52 matrix with entries in {0, 1, -1, i, -i} is doable.
You can encode the matrix and provide decoding instructions rather than the matrix itself.
One possible encoding, since the entries can only take 5 values, take them as 5-ary digits; then each row can be thought of as the 5-ary expansion of a number. If we agree on the digits and communicate the numbers, we're good.
Here is a random matrix a
with entries in {0, 1, -1, i, -i}:
sage: G = GaussianIntegers()
sage: U = [0, 1, -1, i, -i]
sage: a = matrix(G, 52, lambda i, j: U[randint(0, 4)])
Encoded matrix:
sage: b = [Integer(tuple(U.index(e) for e in row), 5) for row in a]
sage: print(b)
[1986835196674783292709127771671427698, 372532889760445898415871372893604877,
29903254311383361818758881193795318, 1358695302115484662298806740046547384,
1537321601024823802437657316988965568, 807200500103255107975400681439180354,
567350510853383980331713019521919561, 1502850803304703506587108729499355006,
846884730762028905888265726139310683, 137381915837271267181515478275643286,
522105367460276163750943030646864364, 1062521690576328608603843582516522599,
899547582492594668160772320652245190, 767732247768012897653127687752209191,
629354811960707798077793065391805161, 922202162939977177914455168534168765,
1729869497057901779087386639626774141, 1868018985439944039499425518652161649,
1296299082686624643142119402841062894, 1064799841987832209268578137251968874,
2155066789175869415783929309121456698, 267366791364966820259349410583047599,
1632002494019334195780113340724191796, 2192661273536615612340019587291366905,
1762917404578120599684457836032844498, 228986171419406644876547615831863389,
2101920423365829833128536344495944345, 660985714605962040665526677335410210,
873334831095240711598788236281716427, 1744121894438415469560277438117935725,
2210059965689974187926035573546483126, 1594508474721458635473949546648185838,
518211385383214049244941993118895991, 231206763245123017363282654207827645,
1748059359372987512622900717899928645, 259988738192311572545249238464600548,
2007721547194093983826996655201647232, 1240843285105582949996674635390136465,
1736982326629685244276013105887136315, 435682393610221223713098672542297123,
66566788503415822985489945441756435, 1141561970732274264554486688206105649,
2044822779971527183978088623745613537, 17299608296692077102235770236630252,
780853597789891512314851615527578148, 427428566224687826328803693567479441,
1922351158930802787176924223394683886, 2104373328835002410314401979576425296,
1317300586469460326137557530572476230, 1736284365530465805899187629996562866,
2132757211837100962505268985637520292, 147031314086172436786678135727403627]
To decode:
sage: aa = matrix(G, 52, [[U[d] for d in r.digits(5, padto=52)] for r in b])
sage: aa == a
True
Here is a function that takes a matrix as an argument, and returns "short enough code" to recreate that matrix.
def matrix_code(a):
r"""
Return code for a matrix with entries in {0, 1, -1, i, -i}.
EXAMPLE::
sage: G = GaussianIntegers()
sage: U = [0, 1, -1, i, -i]
sage: a = matrix(G, 52, lambda i, j: U[randint(0, 4)])
sage: matrix_code(a)
...
"""
G = GaussianIntegers()
U = [0, 1, -1, i, -i]
m = a.nrows()
n = a.ncols()
b = [Integer(tuple(U.index(e) for e in row), 5) for row in a]
print(f"""
G = GaussianIntegers()
U = [0, 1, -1, i, -i]
b = {b}
a = matrix(G, {m}, {n}, [[U[d] for d in r.digits(5, padto={n})] for r in b])
""")
Run it on your matrix. Edit your question, pasting the output. Then we can all play with the same matrix.
5 | No.5 Revision |
Why is this happening and is there another way I can avoid large rounding errors when taking the inverse?
This is happening because CC
and CDF
use floating-point numbers,
and computations are thus inexact and subject to rounding errors.
Instead of working with CC
or CDF
, one could
use matrices over GaussianIntegers()
or ZZ[i]
or QQ[i]
or QQbar
for exact computations
use matrices over CBF
("complex ball field")
for floating-point computations with rigorous error bounds
I'm not really sure how to provide an example of this error occurring since the smallest example of the array I am working with is (52x52).
Communicating a 52 x 52 matrix with entries in {0, 1, -1, i, -i} is doable.
You can encode the matrix and provide decoding instructions rather than the matrix itself.
One possible encoding, since the entries can only take 5 values, take them as 5-ary digits; then each row can be thought of as the 5-ary expansion of a number. If we agree on the digits and communicate the numbers, we're good.
Here is a random matrix a
with entries in {0, 1, -1, i, -i}:
sage: G = GaussianIntegers()
sage: U = [0, 1, -1, i, -i]
sage: a = matrix(G, 52, lambda i, j: U[randint(0, 4)])
Encoded matrix:
sage: b = [Integer(tuple(U.index(e) for e in row), 5) for row in a]
sage: print(b)
[1986835196674783292709127771671427698, 372532889760445898415871372893604877,
29903254311383361818758881193795318, 1358695302115484662298806740046547384,
1537321601024823802437657316988965568, 807200500103255107975400681439180354,
567350510853383980331713019521919561, 1502850803304703506587108729499355006,
846884730762028905888265726139310683, 137381915837271267181515478275643286,
522105367460276163750943030646864364, 1062521690576328608603843582516522599,
899547582492594668160772320652245190, 767732247768012897653127687752209191,
629354811960707798077793065391805161, 922202162939977177914455168534168765,
1729869497057901779087386639626774141, 1868018985439944039499425518652161649,
1296299082686624643142119402841062894, 1064799841987832209268578137251968874,
2155066789175869415783929309121456698, 267366791364966820259349410583047599,
1632002494019334195780113340724191796, 2192661273536615612340019587291366905,
1762917404578120599684457836032844498, 228986171419406644876547615831863389,
2101920423365829833128536344495944345, 660985714605962040665526677335410210,
873334831095240711598788236281716427, 1744121894438415469560277438117935725,
2210059965689974187926035573546483126, 1594508474721458635473949546648185838,
518211385383214049244941993118895991, 231206763245123017363282654207827645,
1748059359372987512622900717899928645, 259988738192311572545249238464600548,
2007721547194093983826996655201647232, 1240843285105582949996674635390136465,
1736982326629685244276013105887136315, 435682393610221223713098672542297123,
66566788503415822985489945441756435, 1141561970732274264554486688206105649,
2044822779971527183978088623745613537, 17299608296692077102235770236630252,
780853597789891512314851615527578148, 427428566224687826328803693567479441,
1922351158930802787176924223394683886, 2104373328835002410314401979576425296,
1317300586469460326137557530572476230, 1736284365530465805899187629996562866,
2132757211837100962505268985637520292, 147031314086172436786678135727403627]
To decode:
sage: aa = matrix(G, 52, [[U[d] for d in r.digits(5, padto=52)] for r in b])
sage: aa == a
True
Here is a function that takes a matrix as an argument, and returns "short enough code" to recreate that matrix.
def matrix_code(a):
r"""
Return code for a matrix with entries in {0, 1, -1, i, -i}.
EXAMPLE::
sage: G = GaussianIntegers()
sage: U = [0, 1, -1, i, -i]
sage: a = matrix(G, 52, lambda i, j: U[randint(0, 4)])
sage: matrix_code(a)
...
"""
G = GaussianIntegers()
U = [0, 1, -1, i, -i]
m = a.nrows()
n = a.ncols()
b = [Integer(tuple(U.index(e) for e in row), 5) for row in a]
print(f"""
G = GaussianIntegers()
U = [0, 1, -1, i, -i]
b = {b}
a = matrix(G, {m}, {n}, [[U[d] for d in r.digits(5, padto={n})] for r in b])
""")
Run it on your matrix. Edit your question, pasting the output. Then we can all play with the same matrix.
(Added after the question was updated to provide a concrete example.)
Thanks for the concrete example. It seems to uncover several bugs!
Define the gaussian integers and their fraction field:
sage: Zi = GaussianIntegers()
sage: Qi = Zi.fraction_field()
The "digits" for decoding the encoded matrix in the updated question:
sage: U = [0, 1, -1, i, -i]
The decoded matrix:
sage: a = matrix(Zi, 52, [[U[d] for d in r.digits(5, padto=52)] for r in b])
Several variations of the same matrix, varying the base ring:
sage: a_Zi = a
sage: a_Qi = a.change_ring(Qi)
sage: a_CC = a.change_ring(CC)
sage: a_CDF = a.change_ring(CDF)
sage: a_QQbar = a_Qi.change_ring(QQbar)
First bug: changing ring directly from the gaussian integers to QQbar
fails:
sage: a.change_ring(QQbar)
Traceback (most recent call last)
...
AttributeError: 'AbsoluteOrder_with_category' object has no attribute 'polynomial'
Second bug: all our matrices don't compare equal:
sage: aa = [a_Zi, a_Qi, a_QQbar, a_CC, a_CDF]
sage: print('\n'.join(' '.join(str(int(a == b)) for b in aa) for a in aa))
1 1 0 1 1
1 1 0 1 1
0 0 1 1 1
1 1 1 1 1
1 1 1 1 1
Third bug: the determinant computation over CC fails:
sage: ringdets = [('ZZ[i]', a_Zi.det()),
....: ('QQ[i]', a_Qi.det()),
....: ('QQbar', a_QQbar.det()),
....: ('CC', a_CC.det()),
....: ('CDF', a_CDF.det())]
sage: print('\n'.join('%5s %18s' % ringdet for ringdet in ringdets))
ZZ[i] 2
QQ[i] 2
QQbar 2
CC 512.000000000000*I
CDF 2.0
6 | No.6 Revision |
Why is this happening and is there another way I can avoid large rounding errors when taking the inverse?
This is happening because CC
and CDF
use floating-point numbers,
and computations are thus inexact and subject to rounding errors.
Instead of working with CC
or CDF
, one could
use matrices over GaussianIntegers()
or ZZ[i]
or QQ[i]
or QQbar
for exact computations
use matrices over CBF
("complex ball field")
for floating-point computations with rigorous error bounds
I'm not really sure how to provide an example of this error occurring since the smallest example of the array I am working with is (52x52).
Communicating a 52 x 52 matrix with entries in {0, 1, -1, i, -i} is doable.
You can encode the matrix and provide decoding instructions rather than the matrix itself.
One possible encoding, since the entries can only take 5 values, take them as 5-ary digits; then each row can be thought of as the 5-ary expansion of a number. If we agree on the digits and communicate the numbers, we're good.
Here is a random matrix a
with entries in {0, 1, -1, i, -i}:
sage: G = GaussianIntegers()
sage: U = [0, 1, -1, i, -i]
sage: a = matrix(G, 52, lambda i, j: U[randint(0, 4)])
Encoded matrix:
sage: b = [Integer(tuple(U.index(e) for e in row), 5) for row in a]
sage: print(b)
[1986835196674783292709127771671427698, 372532889760445898415871372893604877,
29903254311383361818758881193795318, 1358695302115484662298806740046547384,
1537321601024823802437657316988965568, 807200500103255107975400681439180354,
567350510853383980331713019521919561, 1502850803304703506587108729499355006,
846884730762028905888265726139310683, 137381915837271267181515478275643286,
522105367460276163750943030646864364, 1062521690576328608603843582516522599,
899547582492594668160772320652245190, 767732247768012897653127687752209191,
629354811960707798077793065391805161, 922202162939977177914455168534168765,
1729869497057901779087386639626774141, 1868018985439944039499425518652161649,
1296299082686624643142119402841062894, 1064799841987832209268578137251968874,
2155066789175869415783929309121456698, 267366791364966820259349410583047599,
1632002494019334195780113340724191796, 2192661273536615612340019587291366905,
1762917404578120599684457836032844498, 228986171419406644876547615831863389,
2101920423365829833128536344495944345, 660985714605962040665526677335410210,
873334831095240711598788236281716427, 1744121894438415469560277438117935725,
2210059965689974187926035573546483126, 1594508474721458635473949546648185838,
518211385383214049244941993118895991, 231206763245123017363282654207827645,
1748059359372987512622900717899928645, 259988738192311572545249238464600548,
2007721547194093983826996655201647232, 1240843285105582949996674635390136465,
1736982326629685244276013105887136315, 435682393610221223713098672542297123,
66566788503415822985489945441756435, 1141561970732274264554486688206105649,
2044822779971527183978088623745613537, 17299608296692077102235770236630252,
780853597789891512314851615527578148, 427428566224687826328803693567479441,
1922351158930802787176924223394683886, 2104373328835002410314401979576425296,
1317300586469460326137557530572476230, 1736284365530465805899187629996562866,
2132757211837100962505268985637520292, 147031314086172436786678135727403627]
To decode:
sage: aa = matrix(G, 52, [[U[d] for d in r.digits(5, padto=52)] for r in b])
sage: aa == a
True
Here is a function that takes a matrix as an argument, and returns "short enough code" to recreate that matrix.
def matrix_code(a):
r"""
Return code for a matrix with entries in {0, 1, -1, i, -i}.
EXAMPLE::
sage: G = GaussianIntegers()
sage: U = [0, 1, -1, i, -i]
sage: a = matrix(G, 52, lambda i, j: U[randint(0, 4)])
sage: matrix_code(a)
...
"""
G = GaussianIntegers()
U = [0, 1, -1, i, -i]
m = a.nrows()
n = a.ncols()
b = [Integer(tuple(U.index(e) for e in row), 5) for row in a]
print(f"""
G = GaussianIntegers()
U = [0, 1, -1, i, -i]
b = {b}
a = matrix(G, {m}, {n}, [[U[d] for d in r.digits(5, padto={n})] for r in b])
""")
Run it on your matrix. Edit your question, pasting the output. Then we can all play with the same matrix.
(Added after the question was updated to provide a concrete example.)
Thanks for the concrete example. It seems to uncover several bugs!
Define the gaussian integers and their fraction field:
sage: Zi = GaussianIntegers()
sage: Qi = Zi.fraction_field()
The "digits" for decoding the encoded matrix in the updated question:
sage: U = [0, 1, -1, i, -i]
The decoded matrix:
sage: a = matrix(Zi, 52, [[U[d] for d in r.digits(5, padto=52)] for r in b])
Several variations of the same matrix, varying the base ring:
sage: a_Zi = a
sage: a_Qi = a.change_ring(Qi)
sage: a_CC = a.change_ring(CC)
sage: a_CDF = a.change_ring(CDF)
sage: a_QQbar = a_Qi.change_ring(QQbar)
First bug: changing ring directly from the gaussian integers to QQbar
fails:
sage: a.change_ring(QQbar)
Traceback (most recent call last)
...
AttributeError: 'AbsoluteOrder_with_category' object has no attribute 'polynomial'
Second bug: all our matrices don't compare equal:
sage: aa = [a_Zi, a_Qi, a_QQbar, a_CC, a_CDF]
sage: print('\n'.join(' '.join(str(int(a == b)) for b in aa) for a in aa))
1 1 0 1 1
1 1 0 1 1
0 0 1 1 1
1 1 1 1 1
1 1 1 1 1
Third bug: the determinant computation over CC fails:
sage: ringdets = [('ZZ[i]', a_Zi.det()),
....: ('QQ[i]', a_Qi.det()),
....: ('QQbar', a_QQbar.det()),
....: ('CC', a_CC.det()),
....: ('CDF', a_CDF.det())]
sage: print('\n'.join('%5s %18s' % ringdet for ringdet in ringdets))
ZZ[i] 2
QQ[i] 2
QQbar 2
CC 512.000000000000*I
CDF 2.0
I don't observe problems when taking the inverse:
sage: b_Zi = a_Zi.inverse()
sage: b_Qi = a_Qi.inverse()
sage: b_QQbar = a_QQbar.inverse()
sage: b_CDF = a_CDF.inverse()
sage: b_CC = a_CC.inverse()
and the inverse seems to be computed correctly; the result for CC is rather more accurate than for CDF.
sage: print(b_Zi[:8, :4])
[ -1 1 0 0]
[ -2 1 -1 -1]
[ 0 0 -1 -1]
[ 0 0 0 1/2]
[ 0 0 0 1/2]
[ 0 1 -1 -1]
[ -1 1 -1 -1]
[ 1 0 -1 -1/2]
sage: print(b_Qi[:8, :4])
[ -1 1 0 0]
[ -2 1 -1 -1]
[ 0 0 -1 -1]
[ 0 0 0 1/2]
[ 0 0 0 1/2]
[ 0 1 -1 -1]
[ -1 1 -1 -1]
[ 1 0 -1 -1/2]
sage: print(b_QQbar[:8, :4])
[ -1 1 0 0]
[ -2 1 -1 -1]
[ 0 0 -1 -1]
[ 0 0 0 1/2]
[ 0 0 0 1/2]
[ 0 1 -1 -1]
[ -1 1 -1 -1]
[ 1 0 -1 -1/2]
sage: print(b_CDF[:8, :4])
[ -0.9999999999999998 1.0000000000000004 -7.771561172376096e-16 -2.220446049250313e-16]
[ -1.9999999999999996 1.0000000000000009 -1.0 -1.0000000000000004]
[ 1.1102230246251565e-16 5.551115123125783e-17 -1.0 -0.9999999999999999]
[ -6.106226635438361e-16 2.7755575615628914e-16 2.7755575615628914e-16 0.5000000000000002]
[-1.1102230246251568e-16 -1.1102230246251563e-16 0.0 0.4999999999999999]
[ 5.551115123125783e-16 0.9999999999999997 -1.0000000000000004 -1.0000000000000004]
[ -1.0000000000000004 1.0000000000000009 -1.0000000000000004 -1.0]
[ 0.9999999999999998 1.1102230246251565e-16 -1.0000000000000004 -0.5000000000000002]
sage: print(b_CC[:8, :4])
[ -1.00000000000000 1.00000000000000 0.000000000000000 0.000000000000000]
[ -2.00000000000000 1.00000000000000 -1.00000000000000 -1.00000000000000]
[ 0.000000000000000 0.000000000000000 -1.00000000000000 -1.00000000000000]
[ 0.000000000000000 0.000000000000000 0.000000000000000 0.500000000000000]
[ 0.000000000000000 0.000000000000000 0.000000000000000 0.500000000000000]
[ 0.000000000000000 1.00000000000000 -1.00000000000000 -1.00000000000000]