127 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Factor
		
	
	
		
		
			
		
	
	
			127 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Factor
		
	
	
| 
								 | 
							
								USING: kernel
							 | 
						||
| 
								 | 
							
								sequences
							 | 
						||
| 
								 | 
							
								namespaces
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								math
							 | 
						||
| 
								 | 
							
								math.vectors
							 | 
						||
| 
								 | 
							
								math.matrices
							 | 
						||
| 
								 | 
							
								;
							 | 
						||
| 
								 | 
							
								IN: adsoda.solution2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								! -------------------
							 | 
						||
| 
								 | 
							
								! correctif solution
							 | 
						||
| 
								 | 
							
								! ---------------
							 | 
						||
| 
								 | 
							
								SYMBOL: matrix
							 | 
						||
| 
								 | 
							
								: MIN-VAL-adsoda ( -- x ) 0.00000001
							 | 
						||
| 
								 | 
							
								! 0.000000000001 
							 | 
						||
| 
								 | 
							
								;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: zero? ( x -- ? ) 
							 | 
						||
| 
								 | 
							
								    abs MIN-VAL-adsoda <
							 | 
						||
| 
								 | 
							
								;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								! [ number>string string>number ] map 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: with-matrix ( matrix quot -- )
							 | 
						||
| 
								 | 
							
								    [ swap matrix set call matrix get ] with-scope ; inline
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: nth-row ( row# -- seq ) matrix get nth ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: change-row ( row# quot -- seq ) ! row# quot -- | quot: seq -- seq )
							 | 
						||
| 
								 | 
							
								    matrix get swap change-nth ; inline
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: exchange-rows ( row# row# -- ) matrix get exchange ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: rows ( -- n ) matrix get length ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: cols ( -- n ) 0 nth-row length ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: skip ( i seq quot -- n )
							 | 
						||
| 
								 | 
							
								    over [ find-from drop ] dip length or ; inline
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: first-col ( row# -- n )
							 | 
						||
| 
								 | 
							
								    #! First non-zero column
							 | 
						||
| 
								 | 
							
								    0 swap nth-row [ zero? not ] skip ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: clear-scale ( col# pivot-row i-row -- n )
							 | 
						||
| 
								 | 
							
								    [ over ] dip nth dup zero? [
							 | 
						||
| 
								 | 
							
								        3drop 0
							 | 
						||
| 
								 | 
							
								    ] [
							 | 
						||
| 
								 | 
							
								        [ nth dup zero? ] dip swap [
							 | 
						||
| 
								 | 
							
								            2drop 0
							 | 
						||
| 
								 | 
							
								        ] [
							 | 
						||
| 
								 | 
							
								            swap / neg
							 | 
						||
| 
								 | 
							
								        ] if
							 | 
						||
| 
								 | 
							
								    ] if ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: (clear-col) ( col# pivot-row i -- )
							 | 
						||
| 
								 | 
							
								    [ [ clear-scale ] 2keep [ n*v ] dip v+ ] change-row ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: rows-from ( row# -- slice )
							 | 
						||
| 
								 | 
							
								    rows dup <slice> ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: clear-col ( col# row# rows -- )
							 | 
						||
| 
								 | 
							
								    [ nth-row ] dip [ [ 2dup ] dip (clear-col) ] each 2drop ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: do-row ( exchange-with row# -- )
							 | 
						||
| 
								 | 
							
								    [ exchange-rows ] keep
							 | 
						||
| 
								 | 
							
								    [ first-col ] keep
							 | 
						||
| 
								 | 
							
								    dup 1 + rows-from clear-col ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: find-row ( row# quot -- i elt )
							 | 
						||
| 
								 | 
							
								    [ rows-from ] dip find ; inline
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: pivot-row ( col# row# -- n )
							 | 
						||
| 
								 | 
							
								    [ dupd nth-row nth zero? not ] find-row 2nip ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: (echelon) ( col# row# -- )
							 | 
						||
| 
								 | 
							
								    over cols < over rows < and [
							 | 
						||
| 
								 | 
							
								        2dup pivot-row [ over do-row 1 + ] when*
							 | 
						||
| 
								 | 
							
								        [ 1 + ] dip (echelon)
							 | 
						||
| 
								 | 
							
								    ] [
							 | 
						||
| 
								 | 
							
								        2drop
							 | 
						||
| 
								 | 
							
								    ] if ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: echelon ( matrix -- matrix' )
							 | 
						||
| 
								 | 
							
								    [ 0 0 (echelon) ] with-matrix ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: nonzero-rows ( matrix -- matrix' )
							 | 
						||
| 
								 | 
							
								    [ [ zero? ] all? not ] filter ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: null/rank ( matrix -- null rank )
							 | 
						||
| 
								 | 
							
								    echelon dup length swap nonzero-rows length [ - ] keep ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: leading ( seq -- n elt ) [ zero? not ] find ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: reduced ( matrix' -- matrix'' )
							 | 
						||
| 
								 | 
							
								    [
							 | 
						||
| 
								 | 
							
								        rows <reversed> [
							 | 
						||
| 
								 | 
							
								            dup nth-row leading drop
							 | 
						||
| 
								 | 
							
								            dup [ swap dup clear-col ] [ 2drop ] if
							 | 
						||
| 
								 | 
							
								        ] each
							 | 
						||
| 
								 | 
							
								    ] with-matrix ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: basis-vector ( row col# -- )
							 | 
						||
| 
								 | 
							
								    [ clone ] dip
							 | 
						||
| 
								 | 
							
								    [ swap nth neg recip ] 2keep
							 | 
						||
| 
								 | 
							
								    [ 0 spin set-nth ] 2keep
							 | 
						||
| 
								 | 
							
								    [ n*v ] dip
							 | 
						||
| 
								 | 
							
								    matrix get set-nth ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: nullspace ( matrix -- seq )
							 | 
						||
| 
								 | 
							
								    echelon reduced dup empty? [
							 | 
						||
| 
								 | 
							
								        dup first length identity-matrix [
							 | 
						||
| 
								 | 
							
								            [
							 | 
						||
| 
								 | 
							
								                dup leading drop
							 | 
						||
| 
								 | 
							
								                dup [ basis-vector ] [ 2drop ] if
							 | 
						||
| 
								 | 
							
								            ] each
							 | 
						||
| 
								 | 
							
								        ] with-matrix flip nonzero-rows
							 | 
						||
| 
								 | 
							
								    ] unless ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: 1-pivots ( matrix -- matrix )
							 | 
						||
| 
								 | 
							
								    [ dup leading nip [ recip v*n ] when* ] map ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: solution ( matrix -- matrix )
							 | 
						||
| 
								 | 
							
								    echelon nonzero-rows reduced 1-pivots ;
							 | 
						||
| 
								 | 
							
								
							 |