incr-set prlevel 1
if #0=3 START
incr-set prlevel -1
;;; Usage:
;;; 	<random_element f d e
;;;
;;; Chooses a random element e of degree d in the 
;;; column space of f.  Thus if
;;;    f: A0 --> B0, then
;;;    e: E0 --> B0
;;; is a map from a free module E0 of rank 1
;;; generated in degree d.  e is set to 0 if 
;;; A0 has no generators of degrees <=d.
;;; 
incr-set prlevel 1
jump END
;;; Parameters:
;;;          f a matrix
;;;          d an integer
;;; Output values:
;;;          e a matrix with the same col space as f
;;;
;;;  The method used is to multiply each column of 
;;; f having degree <=d by a random form of the 
;;; appropriated degree, and add.  This is probably
;;; faster than computing a k-basis of the image in
;;; degree d and taking a random element!
;;;
; created 12/18/89 DE
START:
setring #1
<getvars @vars
ncols #1 @n
nrows #1 @numrows

;initialize the loop
<zeromat @numrows 1 @e
setdegs @e
    #1 ;takes the row degrees of f
	#2 ;the desired d

int @n @n+1

loop:
int @n @n-1
if @n=0 finish

submat #1 @col
    ; take all rows
	@n ;take one column
col-deg @col 1 @deg

;test whether this column can contribute:
if @deg>#2 loop

;else multiply by a form of the right degree and add
int @deg #2-@deg
power @vars @deg @power
<random_mat 1 1 @power @power
outer @power @col @col
add @col @e @e
jump loop

finish:
copy @e #3
poly @power 0 ;in case this was never set
poly @col 0 ;in case this was never set
poly @deg 0 ;in case this was never set
kill @vars @n @numrows @e @col @deg @power
END:
incr-set prlevel -1

$;;;;;;;; EXAMPLE SECTION ;;;;;;;;;;;;;;;;;;;;;;;;;
reset

<ring 3 a-z r
<ideal i a b2 c3
setdegs i
    2
    ;
<random_element i 4 x
type x
betti x

listvars

transpose i i'
dsum i i' j
type j
betti j
<random_element j 0 x
type x
betti x

; ;;;;;
;quotient ring situation:
reset
<ring 3 a-z r
<ideal i a b2 c3
setdegs i
    2
    ;
power r 3 r3
std r3 r3
qring r3 q
fetch i i
betti i

<random_element i 5 x
type x
betti x
