gpt4 book ai didi

Haskell 中的函数守卫和 'where' 语法

转载 作者:行者123 更新时间:2023-12-02 03:38:27 30 4
gpt4 key购买 nike

我正在尝试自学 Haskell,因此我决定通过编写一个简单的函数来练习 3x3 矩阵的求逆。这应该很容易,但我尝试的任何事情都无法编译成功。

这是我的代码:

matInv3x3 :: [[Double]] -> [[Double]]
matInv3x3 m
| length m /= 3 = error "wrong number of rows"
| length (m !! 0) /= 3 = error "wrong number of elements in row 0"
| length (m !! 1) /= 3 = error "wrong number of elements in row 1"
| length (m !! 2) /= 3 = error "wrong number of elements in row 2"
| det == 0 = error "zero determinant"
| otherwise = mInv
where a = m !! 0 !! 0
b = m !! 0 !! 1
c = m !! 0 !! 2
d = m !! 1 !! 0
e = m !! 1 !! 1
f = m !! 1 !! 2
g = m !! 2 !! 0
h = m !! 2 !! 1
i = m !! 2 !! 2
det = a*(e*i - f*h) - b*(i*d - f*g) + c*(d*h - e*g)
A = (e*i - f*h) / det
B = -(d*i - f*g) / det
C = (d*h - e*g) / det
D = -(b*i - c*h) / det
E = (a*i - c*g) / det
F = -(a*h - b*g) / det
G = (b*f - c*e) / det
H = -(a*f - c*d) / det
I = (a*e - b*d) / det
mInv = [[A,B,C],[D,E,F],[G,H,I]]

我正在努力防范所有可能出错的事情:错误的列表维度和零行列式。我根据“学习你...”一书中的示例对其进行了建模。如果矩阵的行列式为零,我会尝试依赖惰性求值。

GHCi 不会编译它,引用第 10 行(定义 b 的地方)的 '=' 的解析错误。我确定我缺少一些简单、基本的东西。有人可以指出我做错了什么吗?

更新:

我实现了评论中提出的修复,还纠正了我犯的交换索引错误(之前没有发现,因为代码无法编译)。这是固定代码,它正确地反转 3x3 矩阵:

matInv3x3 :: [[Double]] -> [[Double]]
matInv3x3 m
| length m /= 3 = error "wrong number of rows"
| length (m !! 0) /= 3 = error "wrong number of elements in row 0"
| length (m !! 1) /= 3 = error "wrong number of elements in row 1"
| length (m !! 2) /= 3 = error "wrong number of elements in row 2"
| abs det < 1.0e-15 = error "zero or near-zero determinant"
| otherwise = mInv
where [[a,d,g],[b,e,h],[c,f,i]] = m
det = a*(e*i - f*h) - b*(i*d - f*g) + c*(d*h - e*g)
a' = (e*i - f*h) / det
b' = -(d*i - f*g) / det
c' = (d*h - e*g) / det
d' = -(b*i - c*h) / det
e' = (a*i - c*g) / det
f' = -(a*h - b*g) / det
g' = (b*f - c*e) / det
h' = -(a*f - c*d) / det
i' = (a*e - b*d) / det
mInv = [[a',b',c'],[d',e',f'],[g',h',i']]

最佳答案

一个很好的练习是将此函数推广到任意 nxn 矩阵。如果您有兴趣,这里是一种计算 nxn 行列式的方法。

-- Remove the nth element from a list
remove :: Int -> [a] -> [a]
remove n xs = ys ++ (tail zs)
where
(ys, zs) = splitAt n xs

-- Minor matrix of cofactor C(i,j)
minor :: Int -> Int -> [[a]] -> [[a]]
minor i j xs = remove j $ map (remove i) xs

-- The determinant of a square matrix represented as a list of lists
-- representing column vectors, that is [column].
det :: Num a => [[a]] -> a
det (a:[]) = head a
det m = sum [(-1)^i * (c1 !! i) * det (minor i 0 m) | i <- [0 .. (n-1)]]
where
c1 = head m
n = length m

关于Haskell 中的函数守卫和 'where' 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21744350/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com