2014-02-13 87 views
1

目前我试图让列表的使用功能来创建:OCaml中和创建列表

0 V12 V13 V14 
V21 0 V23 V24 
V31 V32 0 V34 
V41 V42 V43 0 

的方式,我发现这样做是使用论文公式:

(2*V1 - 1)*(2*V2-1) = for spot V(1,2) in the Matrix 
(2*V1 - 1)*(2*V3-1) = for spot V(1,3) in the Matrix 
etc 

因此到目前为止,我有:

let singleState state = 
if state = 0.0 then 0.0 
else 
    ((2.0 *. state) -. 1.0);; 


let rec matrixState v = 
match v with 
| [] -> [] 
| hd :: [] -> v 
| hd :: (nx :: _ as tl) -> 
    singleState hd *. singleState nx :: matrixState tl;; 

我的结果出来是:

float list = [-3.; -3.; -3.; -1.] 

当他们应该列出看起来名单如下:

0 -1 1 -1 
-1 0 -1 1 
1 -1 0 -1 
-1 1 -1 0 

所以,相反,它使列表是制作只有一个名单列表。我也有麻烦搞清楚如何使对角线0

的签名应该是这样的:

val singleState : float list -> float list list = <fun> 
val matrixState : float list list -> float list list = <fun> 

和我得到

val singleState : float -> float = <fun> 
val matrixState : float list -> float list = <fun> 

任何想法?

+0

您所使用的语言为w ritten“OCaml”,大写字母O和大写字母C. http://caml.inria.fr/ocaml/index.en.html –

回答

0

随着一些修正,你的功能会使结果的一行。然后你可以为你需要的每一行调用一次。重复呼叫的好方法可能是List.map

假设这主要是一个学习锻炼,这可能是件好事先制作一个矩阵是这样的:

V11 V12 V13 V14 
V21 V22 V23 V24 
V31 V32 V33 V34 
V41 V42 V43 V44 

我认为这将是一个更容易计算。

然后你可以用零代替对角线。这里有一些代码可以代替对角线:

let replnth r n l = 
    List.mapi (fun i x -> if i = n then r else x) l 

let zerorow row (n, res) = 
    (n - 1, replnth 0.0 n row :: res) 

let zerodiag m = 
    let (_, res) = List.fold_right zerorow m (List.length m - 1, []) in 
    res 
+0

啊是的,这是一个练习,但它说不使用列表。函数会使其变得相当困难 – user081608

+0

如果这是一个练习,我不想为你编写它:-)你可以使用显式递归来打开这些函数。或者你可以编写自己的列表功能版本。 –

0

我宁愿用数组来处理工作。

一个不错的功能,采用的是那么Array.init,它的工作原理是这样,

# Array.init 5 (fun x -> x);; 
- : int array = [|0; 1; 2; 3; 4|] 

我们注意到,发挥我们的数组的大小的作用。

但是当你想要一个矩阵,我们需要建立数组,它是一个有两个呼叫Array.init,最后一个嵌套到第一个实现的Array,

# Array.init 3 (fun row -> Array.init 3 (fun col -> row+col));; 
- : int array array = [|[|0; 1; 2|]; [|1; 2; 3|]; [|2; 3; 4|]|] 

注意,我已经打电话给我变量col表示它们对应于我们矩阵的行索引和列索引的事实。

最后,为您的公式使用的参考矢量V容值[| V1,V2,V3,V4 |],我们需要创建一个包含调用到我们矩阵建设者, (对数组tab的小区n的值保持就像访问,从而tab.(n-1)

并最终导致我们对工作示例,

let vect = [|1;2;3;4|] 

let built_matrix = 
    Array.init 4 (fun row -> 
    Array.init 4 (fun col -> 
     if col=row then 0 
     else vect.(row)+vect.(col))) 

当然,你必须适应它为y我们的便利,以便根据您的要求匹配这段代码。

关于语法的注意事项,
每次重复阵列都可以避免使用OCaml的一些很好的功能。
我们可以在本地打开,像这样一个模块,

let built_matrix = 
let open Array in 
    init 4 (fun row -> 
    init 4 (fun col -> 
     if col=row then 0 
     else vect.(row)+vect.(col))) 

更短,let open Array in ...可以写为Array.(...),下面的优秀UTOP下解释的代码块,说明它(我打算从中获利这个机会,将我们的矩阵的转换列表的列表)。

utop # 
Array.(
    to_list 
    @@ map to_list 
    @@ init 4 (fun r -> 
    init 4 (fun c -> 
     if r = c then 0 
     else vect.(r)+ vect.(c)))) 
;; 
- : int list list = [[0; 3; 4; 5]; [3; 0; 5; 6]; [4; 5; 0; 7]; [5; 6; 7; 0]] 

我希望它能帮助