
// Test various class group routines for non-fundamental discriminants
// SRD
// Last modified March 2014


// Verifies that the following give the same class number 
// for non-fundamental discriminants:
//   ClassNumber(QuadBin)        [DRK or internal]
//   ReducedForms(QuadBin)       [DRK or internal]
//   FundamentalKernel(QuadBin)  [DRK with fix by SRD]
//   PicardGroup(RngOrd)         [Klueners + Pauli]

// Note: ClassGroup(QuadBin) and PicardGroup(RngQuad) 
// work via FundamentalKernel(QuadBin)

// TO DO: ReducedForms test



DISCS := [-d : d in [2 .. 24] | IsFundamentalDiscriminant(-d)] cat
         [ d : d in [2 .. 28] | IsFundamentalDiscriminant(d)];
CONDUCTORS := [2 .. 25];

for d in DISCS do

  QF := QuadraticForms(d);
  h1 := ClassNumber(QF);
  C1 := ClassGroup(QF);

  if d lt 0 then
    assert h1 eq #ReducedForms(QF); // probably not independent
  end if;

  F := NumberField(Polynomial([-d,0,1]));
  ZF := Integers(F);
  CF := ClassGroup(F);
  assert h1 eq #CF;
  assert IsIsomorphic(C1, CF);

  for f in CONDUCTORS do

    n := d*f^2;
    QF := QuadraticForms(n);
    h := ClassNumber(QF);

    if d lt 0 then
      assert h eq #ReducedForms(QF); // probably not independent
    end if;

    K := FundamentalKernel(QF);
    assert h eq h1 * #K;

    O := sub< ZF | f*ZF.2 >;
// TO DO: fix problems
pic := true;
try
    PicO := PicardGroup(O);
catch err; pic := false; print "!"; end try;
if pic then
    assert h eq #PicO;
end if;

    print d, f, h1, h/h1;

  end for;

end for;

