我正在尝试在 Scheme 中编写一个函数,它将使用高斯消除方法计算给定矩阵(以列表列表的形式)的等级。
我会在代码中解释我想做什么,如果有人能告诉我我做错了什么\如何纠正它,我将不胜感激。
在
iter-rows
函数中,我遍历行并对每一行进行高斯消元,使矩阵成为行梯形。below-pivot
将基本上执行给定行中枢轴下方的消除步骤。factor-rec
这里我计算了消元过程中乘以一行所需的因子elimination
函数对枢轴下方的其余行执行消除本身。update-matrix
函数,它将从另一行中减去一行的倍数。#lang racket
(define (rank matrix)
(define (iter-rows index rows-len matrix)
(if (= index rows-len)
matrix
(let ((pivot (list-ref (list-ref matrix index) index)))
(if (= pivot 0)
(iter-rows (+ index 1) rows-len matrix)
(begin
(below-pivot (+ index 1) rows-len matrix pivot index)
(iter-rows (+ index 1) rows-len matrix)
)
)
)
)
)
(define (below-pivot from-index rows-len matrix pivot i)
(if (= from-index rows-len)
matrix
(begin
(factor-rec (+ from-index 1) rows-len matrix i pivot)
(below-pivot (+ from-index 1) rows-len matrix pivot i)
)
)
)
(define (factor-rec j rows-len matrix i pivot)
(if (= j rows-len)
matrix
(begin
(let ([factor (/ (list-ref (list-ref matrix j) i) pivot)])
(elimination i i rows-len matrix j factor)
)
)
)
)
(define (elimination k i rows-len matrix j factor)
(if (= k rows-len)
matrix
(begin
(update-matrix matrix j k i factor)
(elimination (+ k 1) i rows-len matrix j factor)
)
)
)
(define (update-matrix matrix j k i factor)
(let ((new-cdr (- (list-ref (list-ref matrix j) k)
(* factor (list-ref (list-ref matrix i) k)))))
(list (list-ref matrix i)
(cons new-cdr (list-tail (list-ref matrix j) k)))
)
)
(let ((rows-len (length matrix)))
(iter-rows 0 rows-len matrix)
)
(define (count-nonzero-rows matrix)
(let loop ((matrix matrix) (rank- 0))
(cond ((null? matrix) rank-)
((not (all-zeroes? (car matrix))) (loop (cdr matrix) (+ rank- 1)))
(else (loop (cdr matrix) rank-)))))
(let* ((rank (count-nonzero-rows matrix)))
rank)
)
(define (all-zeroes? row)
(for/and ([x row]) (= x 0)))
我是 Scheme 的新手,所以也很感激任何其他提示。
谢谢。
我想你想要这样的东西:
#lang racket
(define (extract matrix i j)
(vector-ref (vector-ref matrix i) j))
(define (swap-rows! matrix i j)
(let ((row-i (vector-ref matrix i))
(row-j (vector-ref matrix j)))
(vector-set! matrix i row-j)
(vector-set! matrix j row-i)))
(define (scale-row! matrix i factor)
(define (vector-scale vec factor)
(vector-map (curry * factor) vec))
(let* ((row (vector-ref matrix i))
(scaled-row (vector-scale row factor)))
(vector-set! matrix i scaled-row)))
(define (eliminate-rows! matrix i j pivot)
(define (eliminate-row! matrix i j pivot)
(when (< i (vector-length matrix))
(let* ((element-i-j (extract matrix i j))
(factor (/ element-i-j pivot)))
(scale-row! matrix i factor)
(eliminate-row! matrix (add1 i) j pivot))))
(eliminate-row! matrix (add1 i) j pivot))
(define (gaussian-rank matrix (i 0) (j 0) (rank 0))
(cond ((>= i (vector-length matrix)) rank)
((zero? (extract matrix i j)) (gaussian-rank matrix (add1 i) j rank))
(else
(swap-rows! matrix i rank)
(let ((pivot (extract matrix rank j)))
(when (not (zero? pivot))
(scale-row! matrix rank (/ 1 pivot))
(eliminate-rows! matrix rank j pivot))
(gaussian-rank matrix (add1 i) (add1 j) (add1 rank))))))
(define mat (vector #(1 2 3) #(0 1 2) #(0 0 1)))
(gaussian-rank mat) ;;=> 1