The functions returns true, if the Penrose relations A*B*A == A, B*A*B == B, A*B==transpose(A*B) and B*A=transpose(B*A)) are satisfied. In case of an inexact field the relation should hold up to a threshold. In case of two chain complexes, these relation should hold for each pair of pseudo inverse differentials.
i1 : needsPackage "RandomComplexes" o1 = RandomComplexes o1 : Package |
i2 : setRandomSeed "a pretty good example"; |
i3 : h={2,2} o3 = {2, 2} o3 : List |
i4 : r={3} o4 = {3} o4 : List |
i5 : C=randomChainComplex(h,r,Height=>100,ZeroMean=>true) 5 5 o5 = ZZ <-- ZZ 0 1 o5 : ChainComplex |
i6 : C.dd 5 5 o6 = 0 : ZZ <------------------------------------ ZZ : 1 | 1546 30 2470 -4255 -821 | | 632 1576 -1296 3098 826 | | -377 -983 -815 1588 -889 | | 602 130 2096 -4119 57 | | -2313 -1407 -307 -830 521 | o6 : ChainComplexMap |
i7 : CQ=C**QQ 5 5 o7 = QQ <-- QQ 0 1 o7 : ChainComplex |
i8 : CR=C**RR 5 5 o8 = RR <-- RR 53 53 0 1 o8 : ChainComplex |
i9 : CRplus = pseudoInverse CR 5 5 o9 = RR <-- RR 53 53 -1 0 o9 : ChainComplex |
i10 : arePseudoInverses(CR,CRplus,Threshold=>1e-10) o10 = true |
i11 : arePseudoInverses(CR,CRplus,Threshold=>1e-1000) o11 = true |
i12 : CQplus = pseudoInverse CQ 5 5 o12 = QQ <-- QQ <-- 0 -1 0 1 o12 : ChainComplex |
i13 : CRplus.dd 5 5 o13 = -1 : RR <------------------------------------------------------------------------ RR : 0 53 | .000118165 .0000277114 .0000837524 -.0000345714 -.000242182 | 53 | -.0000350254 .000195274 -.000230323 .0000878808 -.0000398381 | | .0000551618 -.000013564 -.00000307303 .0000283795 -.0000409136 | | -.000032967 .000030606 .0000868877 -.0000937862 -.0000779539 | | -.000132106 .000180547 -.000322462 .000131406 .000167433 | o13 : ChainComplexMap |
i14 : CQplus.dd 5 5 o14 = -1 : QQ <------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- QQ : 0 | 71151349234648083/602134959628339728532 8343005942002339/301067479814169864266 12607564180912259/150533739907084932133 -20816677525577215/602134959628339728532 -72913216530598587/301067479814169864266 | | -21090035137352797/602134959628339728532 58790772469889187/301067479814169864266 -34671448552663381/150533739907084932133 52916093372716489/602134959628339728532 -11993947552589491/301067479814169864266 | | 8303709139666510/150533739907084932133 -2041838116725840/150533739907084932133 -462595206106534/150533739907084932133 4272072990580713/150533739907084932133 -6158878614523632/150533739907084932133 | | -134125646514711/4068479456948241409 124519948928892/4068479456948241409 707001894857497/8136958913896482818 -381567233960404/4068479456948241409 -634307450213339/8136958913896482818 | | -70269839740806/531921342427861951 96036713556510/531921342427861951 -343048951382053/1063842684855723902 69897643597768/531921342427861951 178122214661423/1063842684855723902 | 5 0 : QQ <----- 0 : 1 0 o14 : ChainComplexMap |
i15 : (CQplus**RR_53).dd 5 5 o15 = -1 : RR <------------------------------------------------------------------------ RR : 0 53 | .000118165 .0000277114 .0000837524 -.0000345714 -.000242182 | 53 | -.0000350254 .000195274 -.000230323 .0000878808 -.0000398381 | | .0000551618 -.000013564 -.00000307303 .0000283795 -.0000409136 | | -.000032967 .000030606 .0000868877 -.0000937862 -.0000779539 | | -.000132106 .000180547 -.000322462 .000131406 .000167433 | 5 0 : RR <----- 0 : 1 53 0 o15 : ChainComplexMap |
i16 : arePseudoInverses(CQ,CQplus) o16 = true |
i17 : Fp=ZZ/nextPrime 10^3 o17 = Fp o17 : QuotientRing |
i18 : Cp=C**Fp 5 5 o18 = Fp <-- Fp 0 1 o18 : ChainComplex |
i19 : Cpplus=pseudoInverse Cp 5 5 o19 = Fp <-- Fp <-- 0 -1 0 1 o19 : ChainComplex |
i20 : Cpplus.dd 5 5 o20 = -1 : Fp <------------------------------- Fp : 0 | -59 120 -141 286 361 | | -385 -144 400 -165 484 | | -217 115 -269 348 55 | | 134 449 -241 -226 222 | | 423 491 311 -354 442 | 5 0 : Fp <----- 0 : 1 0 o20 : ChainComplexMap |
i21 : arePseudoInverses(CQ,CQplus) o21 = true |
i22 : arePseudoInverses(Cp,Cpplus) o22 = true |
Over finite fields our algorithm to compute the pseudo inverse might fail. Hence we need this test to check the assertion.