gpt4 book ai didi

haskell - 多变量函数的导数和对应的带有向量空间包的雅可比行列式

转载 作者:行者123 更新时间:2023-12-03 14:40:40 25 4
gpt4 key购买 nike

我遇到了 vector-space 的问题再次打包。在最近的 post 中,我收到了来自 @mnish 的非常有用的回答。 ,但我只处理了一个仅依赖于 1 个变量的函数。
例如,当我有一个从极坐标映射到笛卡尔坐标的函数时会发生什么

f:(0,oo) x [0,2pi] -> R²
(r,phi) -> (r*cos(phi),r*sin(phi))
这取决于 2 个变量。
我已经用一种非常天真的方法尝试了这一点:
polar :: Double -> Double -> ((Double,Double) :~> (Double,Double))
polar r phi = \(r,phi) -> (((idD) r)*cos( idD phi),((idD) r)*sin( idD phi))
我收到以下错误:
Couldn't match expected type `(Double, Double) :> (Double, Double)'
with actual type `(t0, t1)'
In the expression:
(((idD) r) * cos (idD phi), ((idD) r) * sin (idD phi))
In the expression:
\ (r, phi)
-> (((idD) r) * cos (idD phi), ((idD) r) * sin (idD phi))
In an equation for `polar':
polar r phi
= \ (r, phi)
-> (((idD) r) * cos (idD phi), ((idD) r) * sin (idD phi))
对于一个组件
polarx :: Double -> Double -> ((Double,Double) :~> Double)
polarx r phi = \(r,phi) -> ((idD) r)*cos( idD phi)
我明白了
Couldn't match expected type `Double'
with actual type `(Double, Double)'
Expected type: (Double, Double) :> Double
Actual type: (Double, Double) :> (Double, Double)
In the return type of a call of `idD'
In the first argument of `(*)', namely `((idD) r)'
显然有一些类型障碍,但我不知道是什么问题。
当我想计算这种映射的雅可比行列时,出现了另一个问题。顾名思义,它与线性 map 有关,当然是被包覆盖了,实际上它是基于那些 map 的。但同样,我的 Haskell 知识不足,无法自行得出解决方案。

最佳答案

我终于找到了解决问题的方法,这并不难,但我还是花了一段时间才弄清楚。如果其他人有兴趣,我会提供详细信息。

首先是我的极地情况代码:

polarCoordD :: ((Double,Double) :~> (Double,Double))
polarCoordD = \(r,phi) -> pairD (polarx (r,phi), polary (r,phi))
where polarx :: (Double,Double) :~> Double
polarx = \(r,phi) -> (fst . unpairD $ (idD) (r,phi))*cos( snd . unpairD $ idD (r, phi))
polary :: (Double,Double) :~> Double
polary = \(r,phi) -> (fst . unpairD $ (idD) (r,phi))*sin( snd . unpairD $ idD (r, phi))

关键是使“推导变量” (idD)意识到元组 (r, phi)它包含我想要区分的两个变量。然后我必须通过 unpairD 解压元组并选择结果对的第一部分和第二部分(在 polarxpolary 中)。两者再次包装成一对。也许有一种更优雅的方法可以做到这一点,但这就是我最终理解的方式。

从这里开始,不难进一步研究柱坐标,或者事实上,任何其他弯曲的正交坐标系。
对于圆柱坐标,我获得:
cylCoordD :: (Vec3 Double :~> Vec3 Double)
cylCoordD = \(r,phi,z) -> tripleD (cylx (r,phi,z), cyly (r,phi,z),cylz (0,0,z))
where cylx :: (Double,Double,Double) :~> Double
cylx = \(r,phi,z) -> (fst' . untripleD $ (idD) (r,phi,z))*cos( snd' . untripleD $ idD (r, phi,z))
cyly :: (Double,Double,Double) :~> Double
cyly = \(r,phi,z) -> (fst' . untripleD $ (idD) (r,phi,z))*sin( snd' . untripleD $ idD (r, phi,z))
cylz :: (Double,Double,Double) :~> Double
cylz = \(_,_,z) -> third . untripleD $ idD (0,0,z)
fst' :: (a,b,c) -> a
fst' (x,_,_) = x
snd' :: (a,b,c) -> b
snd' (_,y,_) = y
third :: (a,b,c) -> c
third (_,_,z) = z

在哪里 Vec3 Double属于 type Vec3 a = (a, a, a) .
现在我们甚至可以建立一个变换矩阵:
let transmat = \(r,phi,z) -> powVal $ liftD3 (,,) (normalized $ derivAtBasis (cylCoordD (r,phi,z)) (Left ())) (normalized $ derivAtBasis (cylCoordD (r,phi,z)) (Right (Left ()))) (normalized $ derivAtBasis (cylCoordD (r,phi,z)) (Right (Right ())))

*Main> transmat (2, rad 0, 0)
((1.0,0.0,0.0),(0.0,1.0,0.0),(0.0,0.0,1.0))

*Main> transmat (2, rad 90, 0)
((6.123233995736766e-17,1.0,0.0),(-1.0,6.123233995736766e-17,0.0),(0.0,0.0,1.0))
rad是一个便利功能
rad :: Double -> Double
rad = (pi*) . (*recip 180)

现在将这个“矩阵”转换为 Numeric Prelude的矩阵类型会很有趣。和/或 hmatrix ,但我不确定这是否有用。但是,这仍然是使用 vector-space 的一个很好的例子。 -包裹。

我仍然需要弄清楚线性 map 的用途,尤其是应用。

关于haskell - 多变量函数的导数和对应的带有向量空间包的雅可比行列式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9428525/

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