线性代数学习笔记二

线性代数学习笔记二

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) 把某一行的所有元素乘以同一个非零数

行变换可应用于任何矩阵,

作者: ntestoc

Created: 2018-12-07 Fri 21:38

猜你喜欢

转载自www.cnblogs.com/ntestoc/p/10085360.html