1 ! Copyright (C) 2006 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: kernel math namespaces parser sequences ;
8 : with-matrix ( matrix quot -- )
9 [ swap matrix set call matrix get ] with-scope ; inline
11 : nth-row ( row# -- seq ) matrix get nth ;
13 : nth-col ( col# ignore-rows -- seq )
14 matrix get tail-slice [ nth ] map-with ;
16 : change-row ( row# quot -- | quot: seq -- seq )
17 matrix get swap change-nth ; inline
19 : exchange-rows ( row# row# -- ) matrix get exchange ;
21 : rows ( -- n ) matrix get length ;
23 : cols ( -- n ) 0 nth-row length ;
25 : first-col ( row# -- n )
26 #! First non-zero column
27 0 swap nth-row [ zero? not ] skip ;
29 : clear-scale ( col# pivot-row i-row -- n )
30 >r over r> nth dup zero? [
40 : (clear-col) ( col# pivot-row i -- )
41 [ [ clear-scale ] 2keep >r n*v r> v+ ] change-row ;
43 : (each-row) ( row# -- slice )
46 : each-row ( row# quot -- )
47 >r (each-row) r> each ; inline
49 : clear-col ( col# row# -- )
51 [ >r 2dup r> (clear-col) ] each-row
54 : do-row ( exchange-with row# -- )
55 [ exchange-rows ] keep
59 : find-row ( row# quot -- i elt )
60 >r (each-row) r> find ; inline
62 : pivot-row ( col# row# -- n )
63 [ dupd nth-row nth zero? not ] find-row 2nip ;
65 : (row-reduce) ( col# row# -- )
66 over cols < over rows < and [
67 2dup pivot-row [ over do-row 1+ ] when* >r 1+ r>
73 : row-reduce ( matrix -- matrix' )
74 [ 0 0 (row-reduce) ] with-matrix ;
76 : null/rank ( matrix -- null rank )
77 row-reduce [ [ [ zero? ] all? ] subset ] keep
78 [ length ] 2apply over - ;