无法在ocaml

时间:2016-08-17 13:18:06

标签: matrix ocaml matrix-multiplication

我正在编写一个简单的程序来计算multiplication of two matrix

(* matrix multiplication *)
let multiply_row_per_col (m1 : int array array) (m2 : int array array) = 
    (* create matrix *)
    let nrows = get_num_rows m1 in
    let ncols = get_num_rows m2 in
    let matrix = create_matrix nrows ncols in
    (* evaluation *)
    for i = 0 to nrows - 1 do
        for j = 0 to ncols - 1 do
            let value = sum_row_col (get_row m1 i) (get_col m2 j) in
            Printf.printf "%i,%i -> %i   " i j value;
            matrix.(i).(j) <- value;
            Printf.printf "%i\n" matrix.(i).(j);
        done;
    done;
    (* return value *)
    matrix
;;

但它没有正常工作:矩阵的最后一行是正确的,所有其他行都包含最后一行的值。

utop # matrix;;
- : int array array = [|[|1; 2; 3|]; [|4; 5; 6|]; [|7; 8; 9|]|]
utop # multiply_row_per_col matrix matrix ;;
0,0 -> 30   30
0,1 -> 36   36
0,2 -> 42   42
1,0 -> 66   66
1,1 -> 81   81
1,2 -> 96   96
2,0 -> 102   102
2,1 -> 126   126
2,2 -> 150   150
- : int array array =
[|[|102; 126; 150|]; [|102; 126; 150|]; [|102; 126; 150|]|]

正确的结果应该是:Correct result 如您所见,单个值是正确的但我无法将它们保存在矩阵中。你有什么想法吗?

这里是utop中执行的代码和一些测试,没有使用其他库(无论是Core还是Batteries):

(* 3x3 matrix *)
let matrix = [| 
    [| 1; 2; 3|]; 
    [| 4; 5; 6|]; 
    [| 7; 8; 9|] 
|];;

(* return the cell of the matrix at [i][j] position *)
let get_cell (matrix : int array array) (row : int) (col : int) : int = 
    Array.get (Array.get matrix row) col
;;

(* return the n-th row *)
let get_row (matrix : int array array) (n : int) : int array = 
    Array.get matrix n
;;

(* return the n-th col of the matrix *)
let get_col (matrix : int array array) (n : int) : int array = 
    Array.map (fun row -> Array.get row n) matrix
;;

(* return the number of rows of a matrix *)
let get_num_rows matrix = 
    Array.length matrix
;;

(* return the number of cols of a matrix *)
let get_num_cols matrix = 
    Array.length (Array.get matrix 0)
;;

(* create NxM matrix *)
let create_matrix rows cols = 
    Array.make rows (Array.make cols 0)
;;

(* multiply each position of row and col, then sum all of them *)
let sum_row_col (row : int array) (col : int array) : int =
    Array.fold_left (+) 0 (Array.map2 ( * ) row col)
;;

(* matrix multiplication *)
let multiply_row_per_col (m1 : int array array) (m2 : int array array) = 
    (* create matrix *)
    let nrows = get_num_rows m1 in
    let ncols = get_num_rows m2 in
    let matrix = create_matrix nrows ncols in
    (* evaluation *)
    for i = 0 to nrows - 1 do
        for j = 0 to ncols - 1 do
            let value = sum_row_col (get_row m1 i) (get_col m2 j) in
            Printf.printf "%i,%i -> %i   " i j value;
            matrix.(i).(j) <- value;
            Printf.printf "%i\n" matrix.(i).(j);
        done;
    done;
    (* return value *)
    matrix
;;

(*
    utop # #use "Matrix_multiplication.ml";;
    val matrix : int array array = [|[|1; 2; 3|]; [|4; 5; 6|]; [|7; 8; 9|]|]
    val get_cell : int array array -> int -> int -> int = <fun>
    val get_row : int array array -> int -> int array = <fun>
    val get_col : int array array -> int -> int array = <fun>
    val get_num_rows : 'a array -> int = <fun>
    val get_num_cols : 'a array array -> int = <fun>
    val create_matrix : int -> int -> int array array = <fun>
    val sum_row_col : int array -> int array -> int = <fun>
    val multiply_row_per_col :
      int array array -> int array array -> int array array = <fun>
    ─( 14:54:52 )─< command 42 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
    utop # get_cell matrix 0 0;;
    - : int = 1
    ─( 14:55:12 )─< command 43 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
    utop # get_cell matrix 2 2;;
    - : int = 9
    ─( 14:56:52 )─< command 45 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
    utop # get_row matrix 1;;
    - : int array = [|4; 5; 6|]
    ─( 14:57:02 )─< command 46 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
    utop # get_col matrix 1;;
    - : int array = [|2; 5; 8|]
    ─( 14:57:08 )─< command 47 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
    utop # create_matrix 3 3;;
    - : int array array = [|[|0; 0; 0|]; [|0; 0; 0|]; [|0; 0; 0|]|]
    ─( 14:57:19 )─< command 48 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
    utop # sum_row_col [|1;2;3|] [|1;2;3|] ;;
    - : int = 14
    ─( 14:57:31 )─< command 49 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
    utop # sum_row_col [|1;2;3|] [|1;4;7|] ;;
    - : int = 30
    ─( 14:57:51 )─< command 50 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
    utop # multiply_row_per_col matrix matrix ;;
    0,0 -> 30   30
    0,1 -> 36   36
    0,2 -> 42   42
    1,0 -> 66   66
    1,1 -> 81   81
    1,2 -> 96   96
    2,0 -> 102   102
    2,1 -> 126   126
    2,2 -> 150   150
    - : int array array =
    [|[|102; 126; 150|]; [|102; 126; 150|]; [|102; 126; 150|]|]
*)

1 个答案:

答案 0 :(得分:3)

问题出在您的create_matrix函数中。它目前的作用是创建一个数组并为每一行使用相同的数组。这意味着在mat.(2).(2)中撰写与在mat.(1).(2)中撰写相同。

为此目的在stdlib中有一个函数:Array.make_matrix,使用它。 ;)