簡體   English   中英

OCaml新手:我將如何實施高斯消除?

[英]New to OCaml: How would I go about implementing Gaussian Elimination?

我是OCaml的新手,我想將高斯消除作為練習來實現。 我可以使用有狀態算法輕松完成它,這意味着在內存中保留一個矩陣,並通過傳遞對它的引用來遞歸地操作它。

然而,這種狀態有點強制性的編程。 我知道OCaml有能力做到這一點,但是我想問一下我是否有一些我沒有想過的聰明的功能方式。

您可以使用Map來模擬矩陣。 鍵是一對引用行和列的整數。 您將需要使用自己的get xy函數來確保x < ny < n ,而不是直接訪問Map (編輯)您可以直接使用Pervasives的比較功能。

module OrderedPairs = struct
    type t = int * int
    let compare = Pervasives.compare
end                     
module Pairs = Map.Make (OrderedPairs)

let get_ n set x y =
    assert( x < n && y < n ); 
    Pairs.find (x,y) set

let set_ n set x y v = 
    assert( x < n && y < n ); 
    Pairs.add (x,y) set v

實際上,擁有一組通用函數( get xy並將get xy set xy為最小值),而不指定實現,將是一個更好的選擇。 然后可以將函數傳遞給函數,或者通過仿函數在模塊中實現(一個更好的解決方案,但是由於您剛接觸OCaml,因此只需執行一些函數即可完成第一步)。 通過這種方式,您可以使用MapArrayHashtbl或一組函數來訪問硬盤驅動器上的文件,以便在需要時實現矩陣。 這是函數式編程的重要方面; 你相信界面過度利用副作用,而不是擔心底層實現 - 因為它被認為是純粹的。

OCaml數組是可變的,並且很難避免像命令式語言中的數組一樣對待它們。

Haskell有不可變數組,但是從Haskell的(有限)經驗來看,在大多數情況下你最終會切換到monadic,mutable數組。 對於某些特定目的,不可變數組可能是驚人的。 我一直想象你可以在Haskell中編寫一個漂亮的動態編程實現,其中數組條目之間的依賴關系完全由它們中的表達式定義。 關鍵是你真的只需要指定一次每個數組條目的內容。 我不認為高斯消除遵循這種模式,因此它似乎不適合不可變數組。 然而,看看它是如何工作的將是有趣的。

到目前為止,答案是使用/模擬可變數據類型,但功能方法是什么樣的?

為了看看,讓我們將問題分解為一些功能組件:

高斯消除涉及一系列行操作,因此首先定義一個取2行和縮放因子的函數,並返回結果行操作結果是有用的。

我們想要的行操作應該從特定行中消除變量(列),因此我們定義一個函數,它接受一對行和一個列索引,並使用先前定義的行操作返回具有該列條目零的修改行。

然后我們定義兩個函數,一個用於將矩陣轉換為三角形,另一個用於將三角矩陣替換為對角線形式(使用先前定義的函數),依次消除每列。 我們可以迭代或遞歸列,矩陣可以定義為列表,向量或列表,向量或數組的數組。 輸入沒有改變,但返回了一個修改過的矩陣,所以我們最終可以做到:

讓out_matrix = to_diagonal(to_triangular in_matrix);

使其起作用的不是數據類型(數組或列表)是否可變,而是它們如何被使用。 這種方法可能不是特別“聰明”,或者是在OCaml中進行高斯消除的最有效方法,但使用純函數可以讓您干凈地表達算法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM