# 线性代数学习笔记二

## 1 线性方程组

```#use "topfind";;
#require "batteries";;
open Batteries

(*** 学习线性代数练习，假定矩阵元素都为浮点数,学习原理，
只实现功能，不做性能优化 **)

exception VectorMismatch

(** 向量放大 *)
let rec vscal s v =
match v with
| [] -> []
| x::xs -> x *. s :: vscal s xs

(** 打印向量 *)
let vprint title v =
print_string title;
print_newline ();
List.iter (Printf.printf "| %-F\t|\n") v

(** 构造一个matrx, col为列数 *)
let make_matrix m col =
if List.length m mod col <> 0 then raise VectorMismatch
else List.ntake col m

let print_matrix m =
let print_row r =
Printf.printf "|";
List.iter (Printf.printf "%-F\t") r;
Printf.printf "|\n"
in
List.iter print_row m

(** 获得矩阵第n行,从0开始 *)
let row_of_matrix = List.at

(** 获得矩阵第n列,从0开始 *)
let col_of_matrix m n = List.map (fun l -> List.at l n) m

(** 返回所有列为一个List *)
let all_cols  = List.transpose

(** 修改矩阵第n行为新的vector *)
let modify_row m n v = List.modify_at n (fun _ -> v) m

(** 返回矩阵的行数 *)
let nrows = List.length

(** 返回矩阵的列数 *)
let ncols m = List.length (List.hd m)

(** 返回向量的和 *)
let sumv = List.fsum

(** 两个向量相加 *)
let vadd =  List.map2 (+.)

(** 向量点积*)
let vector_dot_product v1 v2 =
List.fold_right2 (fun x y total -> total +. x *. y) v1 v2 0.

(** 矩阵乘法 *)
let mul m1 m2 =
if ncols m1 <> nrows m2 then raise VectorMismatch
else let cols_m2 = all_cols m2 in
List.map (fun r ->
(* 每一行 *)
List.map (fun c ->
(* 每一列 *)
vector_dot_product r c
) cols_m2
) m1
;;

(** 倍加变换 m为矩阵， tr为要变换的行, sr为另外一行, sn为另外行的倍数 *)
let row_repl m tr sr sn =
modify_row m tr (vadd (row_of_matrix m tr) (vscal sn (row_of_matrix m sr)))

(** 对换变换 m为矩阵， t,s为要对换的行 *)
let row_interc m t s =
let tr = row_of_matrix m t
and sr = row_of_matrix m s in
modify_row (modify_row m t sr) s tr

(** 倍乘变换 m为矩阵 tr为要变换的行 tn为倍乘系数 *)
let row_scal m tr tn =
modify_row m tr (vscal tn (row_of_matrix m tr))

(*
求解方程:
x - 2y + z  = 0
2y - 8z = 8
-4x + 5y + 9z = -9
*)

(* org_a为系数矩阵 *)
let org_a = make_matrix [1.; -2.; 1.; 0.; 2.; -8.; -4.; 5.; 9.] 3;;
print_matrix org_a;;
(* a为增广矩阵,系数矩阵添加上常数列 *)
let a = make_matrix [1.; -2.; 1.; 0.;
0.; 2.; -8.; 8.;
-4.; 5.; 9.; -9.] 4;;
print_matrix a;;
(* 消元法消去第一个x *)
let a2 = row_repl a 2 0 4. ;;
print_matrix a2;;
(* 第二个位置量系数消为1 *)
let a3 = row_scal a2 1 (1. /. 2.);;
print_matrix a3;;
(* 消去第二个未知量 *)
let a4 = row_repl a3 2 1 3.;;
print_matrix a4;;
(* 消去第一个方程和第二个方程的第三个未知量 *)
let a5 = row_repl a4 1 2 4.;;
print_matrix a5;;
let a6 = row_repl a5 0 2 (-1.);;
print_matrix a6;;
(* 消去第一个方程的第二个未知量 *)
let a7 = row_repl a6 0 1 2.;;
print_matrix a7;;
(* 方程组的解即为a7的第四列 *)
let r = col_of_matrix a7 3;;
(* 验证结果 *)
print_matrix (mul org_a (make_matrix r 1));;
```

1. (倍加变换 replacement) 把某一行换成它本身与另一行的倍数的和
2. (对换变换 interchange) 把两行对换
3. (倍乘变换 scaling) 把某一行的所有元素乘以同一个非零数

Created: 2018-12-07 Fri 21:38