- # The lattice parameter is required when no rays are given, so we
- # pass it just in case.
- return Cone(rays, lattice=L)
+ # The rays are trickier to generate, since we could generate v and
+ # 2*v as our "two rays." In that case, the resuting cone would
+ # have one generating ray. To avoid such a situation, we start by
+ # generating ``r`` rays where ``r`` is the number we want to end
+ # up with.
+ #
+ # However, since we're going to *check* whether or not we actually
+ # have ``r``, we need ``r`` rays to be attainable. So we need to
+ # limit ``r`` to twice the dimension of the ambient space.
+ #
+ r = min(r, 2*d)
+ rays = [L.random_element() for i in range(0, r)]
+
+ # (The lattice parameter is required when no rays are given, so we
+ # pass it just in case ``r == 0``).
+ K = Cone(rays, lattice=L)
+
+ # Now if we generated two of the "same" rays, we'll have fewer
+ # generating rays than ``r``. In that case, we keep making up new
+ # rays and recreating the cone until we get the right number of
+ # independent generators.
+ while r > K.nrays():
+ rays.append(L.random_element())
+ K = Cone(rays)
+
+ return K