我现在和Haskell合作已经有一段时间了,但我远非专家。但我发现编程的功能方法最适合我。
到目前为止,我正在研究一个项目来计算一些严重的东西,比如给定结构辐射的电流和电位。
我按照Conal Elliott撰写的博客(这里是更多Linear Maps),这是非常好的和基本的。
不幸的是,我缺少一个简单的例子:)
更确切地说,我有一条曲线
f:[0,1] in R -> R³
t -> a*e_y + 2*t*e_z
是(0,a,2 * t)处的简单直线。 当我想计算f的导数时,例如对于曲线的长度,我知道数学结果,这非常简单(0,0,2),但我如何在Haskell中实现这一点,特别是使用vector-space包?
我真的想使用这个库因为它的功能,这正是我所采取的方法(但我在Haskell的道路上并没有那么遥远)
到目前为止我所拥有的是:
{-# LANGUAGE Rank2Types, TypeOperators, FlexibleContexts, TypeFamilies #-}
{-# OPTIONS_GHC -Wall #-}
import Numeric.GSL.Integration
import Data.VectorSpace
import Data.Basis
import Data.Cross
import Data.Derivative
import Data.LinearMap
type Vec3 s = Three s
prec :: Double
prec = 1E-9
f1 :: (Floating s, VectorSpace s, Scalar s ~ s) => s -> s
f1 = id
c1 :: Double -> Vec3 Double
c1 = \t -> linearCombo [((v 0 0 1),f1 t),(( v 0 1 0),2)]
derivC :: Double -> Vec3 (Double :> Double)
derivC t = c1 (pureD t)
这是pureD函数的实际实现,到目前为止,我所尝试的任何内容都不能用于编译这个代码片段。我收到以下错误:
tests.hs:26:12:
Couldn't match expected type `Double :> Double'
with actual type `Double'
Expected type: Vec3 (Double :> Double)
Actual type: Vec3 Double
In the return type of a call of `c1'
In the expression: c1 (pureD t)
Failed, modules loaded: none.
还有一个使用矢量空间的图形库,在圆环上甚至有一个例子,其中使用了pureD。我试图推断出这个例子,但我不知道如何将它映射到我的问题。
非常感谢任何帮助。
提前致谢
PS:我不能发布我想要的所有链接,但我愿意提供
答案 0 :(得分:5)
这是一个有趣的图书馆..感谢分享。 虽然我还不了解图书馆的概念, 这段代码怎么样:
{-# LANGUAGE Rank2Types, TypeOperators, FlexibleContexts, TypeFamilies #-}
module Main where
import Data.LinearMap
import Data.Maclaurin
diff :: (Double :~> (Double,Double,Double) ) -> (Double :~> (Double,Double,Double))
diff f = \x -> (atBasis (derivative (f x)) ())
eval :: (Double :~> (Double,Double,Double)) -> Double -> (Double,Double,Double)
eval f x = powVal (f x)
f :: Double :~> (Double,Double,Double)
f x = tripleD (pureD 0,pureD 1,(2*idD) x)
*Main> map (eval f) [0,0.2 .. 1]
[(0.0,1.0,0.0),(0.0,1.0,0.4),(0.0,1.0,0.8),(0.0,1.0,1.2000000000000002),
(0.0,1.0,1.6000000000000003),(0.0,1.0,2.0000000000000004)]
*Main> map (eval (diff f)) [0,0.2 .. 1]
[(0.0,0.0,2.0),(0.0,0.0,2.0),(0.0,0.0,2.0),(0.0,0.0,2.0),(0.0,0.0,2.0),
(0.0,0.0,2.0)]
*Main> map (eval (diff $ diff f)) [0,0.2 .. 1]
[(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0)]
还要尝试g x = tripleD(pureD 0,idD x,(idD * idD)x)(它们似乎代表曲线(0,x,x ^ 2))。
答案 1 :(得分:0)
您可能想尝试使用ad
包,这样可以轻松地自动区分用透明惯用Haskell编写的函数。
$ cabal install ad
$ ghci
Prelude> :m + Numeric.AD
Prelude Numeric.AD> diffF (\t->let a=3 in [0,a,2*t]) 7
[0,0,2]
Prelude Numeric.AD> let f t = let a=3 in [0,a,2*t]
Prelude Numeric.AD> diffF f 17
[0,0,2]