/////////////////////////////////////////////////////////////////////////
// isomorphism
// $Revision: 42149 $
// $Date: 2013-02-20 01:04:53 +1100 (Wed, 20 Feb 2013) $
// $LastChangedBy: kasprzyk $
/////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////
// Specific examples
/////////////////////////////////////////////////////////////////////////
"------\nPolytope Isomorphism: Specific examples\n";

P:=Polytope([
   [ -6, -3, -3, -2, 5, 2, -1, 4 ],
   [ -3, 0, 0, -2, 2, 2, -1, 1 ],
   [ -9/2, -3/2, -3, -2, 7/2, 2, -1, 5/2 ],
   [ -9/2, -3/2, -3, -1/2, 7/2, 2, -1, 1 ],
   [ -3/2, -3/2, 0, -1/2, 1/2, 2, -1, 1 ],
   [ -3/2, 0, -3/2, -1/2, 2, 1/2, -1, 1 ],
   [ -3/2, 0, 0, -1/2, 1/2, 1/2, -1, 1 ],
   [ -15/4, -3/4, -3, -5/4, 11/4, 2, -1, 5/2 ],
   [ 3/4, 3/4, 0, 1/4, -1/4, -1, 1/2, -1/2 ]
]);
Q:=Polytope([
   [ -6, -3, -2, -3, 4, 5, -2, 4 ],
   [ 0, 0, 1, 0, 1, -1, 1, -2 ],
   [ -6, -3/2, -2, -3/2, 4, 7/2, -7/2, 4 ],
   [ -9/2, -3/2, -2, -3/2, 5/2, 7/2, -2, 5/2 ],
   [ -3/2, 0, -1/2, -3/2, 1, 1/2, -1/2, 1 ],
   [ 0, 0, 1, 0, -1/2, -1, 1, -1/2 ],
   [ 3, 3/2, 1, 3/2, -2, -5/2, 5/2, -2 ],
   [ -3/2, -3/4, -1/2, -3/4, 1, -1/4, 1/4, 1 ],
   [ -3/2, -3/4, -1/2, -3/4, 1, 5/4, -5/4, 1 ]
]);
bool,phi:=IsIsomorphic(P,Q);
assert bool and Image(phi,P) eq Q;

P:=Polytope([[1/3]]);
Q:=Polytope([[-1/3]]);
bool,phi:=IsIsomorphic(P,Q);
assert bool and Image(phi,P) eq Q;

P:=Polytope([[1/2,0]]);
Q:=Polytope([[0,1/2]]);
bool,phi:=IsIsomorphic(P,Q);
assert bool and Image(phi,P) eq Q;

/////////////////////////////////////////////////////////////////////////
// Randomly generated examples
/////////////////////////////////////////////////////////////////////////
n:=150;
printf "------\nPolytope Isomorphism: %o random examples\n",n;

procedure report_error(P,Q)
    printf "-----------------------------------------------------------\n\n";
    printf "ERROR! Isomorphism test failed for the following polytopes:\n\n";
    printf "P := Polytope(%o);\n",[Eltseq(v) : v in Vertices(P)];
    printf "Q := Polytope(%o);\n",[Eltseq(v) : v in Vertices(Q)];
end procedure;

function random_basis(d,k)
    success:=false;
    while not success do
        M:=Matrix(d,d,[Random(-k,k) : i in [1..d^2]]);
        success:=Abs(Determinant(M)) eq 1;
    end while;
    return M;
end function;

function random_isomorphism(P,k)
    B:=random_basis(Dimension(Ambient(P)),k);
    return P * B;
end function;

t:=Cputime();
for i in [1..n] do
    d:=Random(2,6);
    P:=RandomPolytope(d,5,3) / Random(1,3);
    Q:=random_isomorphism(P,4);
    bool,phi:=IsIsomorphic(P,Q);
    if not bool or Image(phi,P) ne Q then
        report_error(P,Q);
        assert false;
    end if;
end for;
t:=Cputime(t);
printf "Avrg Time: %os\n",t / n;

/////////////////////////////////////////////////////////////////////////
// Finally, clear the caches
/////////////////////////////////////////////////////////////////////////
"------\nClearing caches\n";

CacheClearToricVariety();
CacheClearToricLattice();
