X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Frandom.py;fp=mjo%2Frandom.py;h=f08c20160ba01072ac2c7bb4f92eaf1b5a0de051;hb=adb4bc82d22373575f3fb96966fd0703781b3cf6;hp=0000000000000000000000000000000000000000;hpb=6957e7f70a89c4ddcc5d9148e1833188ccd7353d;p=sage.d.git diff --git a/mjo/random.py b/mjo/random.py new file mode 100644 index 0000000..f08c201 --- /dev/null +++ b/mjo/random.py @@ -0,0 +1,70 @@ +r""" +Generate random things. +""" + +from sage.matrix.constructor import matrix +from sage.rings.real_lazy import ComplexLazyField +from sage.rings.all import ZZ + +def random_unitary_matrix(F,n): + r""" + Generate a random unitary matrix of size ``n`` with entries + in the field ``F``. + + INPUT: + + - ``F`` -- a field; specifically, a subfield of the complex + numbers having characteristic zero. + + - ``n`` -- integer; the size of the random matrix you want. + + OUTPUT: + + A random ``n``-by-``n`` unitary matrix with entries in ``F``. A + ``ValueError`` is raised if ``F`` is not an appropriate field. + + REFERENCES: + + - Hans Liebeck and Anthony Osborne. The Generation of All Rational + Orthogonal Matrices. The American Mathematical Monthly, Vol. 98, + No. 2. (February, 1991), pp. 131-133. + + SETUP:: + + sage: from mjo.random import random_unitary_matrix + + TESTS:: + + sage: n = ZZ.random_element(10) + sage: U = random_unitary_matrix(QQ,n) + sage: U.is_unitary() + True + sage: U.base_ring() is QQ + True + + :: + + sage: n = ZZ.random_element(10) + sage: K = QuadraticField(-1,'i') + sage: U = random_unitary_matrix(K,n) + sage: U.is_unitary() + True + sage: U.base_ring() is K + True + """ + if not F.is_field(): + raise ValueError("F must be a field") + elif not F.is_subring(ComplexLazyField()): + raise ValueError("F must be a subfield of the complex numbers") + elif not F.characteristic().is_zero(): + raise ValueError("F must have characteristic zero") + + I = matrix.identity(F,n) + A = matrix.random(F,n) + S = A - A.conjugate_transpose() + U = (S-I).inverse()*(S+I) + D = matrix.identity(F,n) + for i in range(n): + if ZZ.random_element(2).is_zero(): + D[i,i] *= F(-1) + return D*U