Производные башни и как использовать пакет вектор-пространства (haskell)
Я работаю с Haskell довольно долгое время, но я далек от того, чтобы быть экспертом. Но я вижу, что функциональный подход к программированию мне подходит лучше всего.
До сих пор я работаю над проектом, чтобы рассчитать некоторые серьезные вещи, такие как токи и потенциалы, излучаемые из данной структуры.
Я следил за блогом, написанным Conal Elliott (здесь еще Линейные карты), что очень приятно и фундаментально.
К сожалению, мне не хватает простого примера:)
Чтобы быть более точным, у меня есть кривая
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: Я не могу опубликовать все ссылки, которые мне бы хотелось, но я желаю предоставить
Ответы
Ответ 1
Это интересная библиотека.. Спасибо за обмен.
Хотя я еще не понимаю концепцию библиотеки,
как насчет этого кода:
{-# 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)).
Ответ 2
Возможно, вы захотите попробовать пакет 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]