1
私はmultiplication of two matrixを計算する簡単なプログラムを書いています。ocamlに配列の値を保存できません
(* 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|]|]
正しい結果が次のようになります。 あなたが見ることができるように、単一の値が正しいですが、私は、マトリックスでそれらを保存することはできません。あなたはなにか考えはありますか?
はここで、他のライブラリが(どちらもコアも電池)を使用されていないコードとutop
で実行いくつかのテストです:
(* 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|]|]
*)
これは機能します! 'Array.make len 0'が要素0をコピーする理由はありますが、' Array.make len array'は実際の配列の代わりに配列の参照をコピーしますか? – incud
@Ignus:Array.makeについては、[documentation](http://caml.inria.fr/pub/docs/manual-ocaml/libref/Array.html)を参照してください。具体的には、 'xが変更可能であれば、それは配列のすべての要素間で共有される。 – Marth