2012-02-16 9 views
14

Pracuję z Haskellem już od jakiegoś czasu, ale nie jestem ekspertem. Ale widzę, że funkcjonalne podejście do programowania pasuje do mnie najlepiej.Wieże pochodne i sposób korzystania z pakietu przestrzeni wektorowej (haskell)

Do tej pory pracuję nad projektem obliczania poważnych rzeczy, takich jak prądy i potencjały emitowane z danej struktury.

Śledziłem blog napisany przez Conal Elliott (tutaj jest więcej Linear Maps), który jest bardzo miły i fundamentalny.

Niestety, brakuje mi prosty przykład :)

być bardziej precyzyjny, mam krzywą

f:[0,1] in R -> R³ 
t -> a*e_y + 2*t*e_z 

który jest prostą linią prostą w punkcie (0, A, 2 * t) . Kiedy chcę obliczyć pochodną f, np. na długość krzywej, znam wynik matematyczny, który jest dość prosty (0,0,2), ale jak mam to osiągnąć w Haskell, zwłaszcza w pakiecie vector-space?

naprawdę chcę używać tej biblioteki ze względu na swoją funkcjonalność, to jest właśnie podejście musiałbym wziąć też (ale nie jestem tak daleko do przodu na drodze Haskell)

Co mam tak daleko jest to :

{-# 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) 

jest to rzeczywista realizacja funkcji pureD, że do tej pory nic próbowałem prace, aby uzyskać ten fragment do kompilacji. Pojawia się następujący błąd:

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. 

Jest też biblioteka grafiki wektorowej, który wykorzystuje przestrzeń i nie ma nawet przykład na torusa, gdzie jest używany pureD. Próbowałem wydedukować przykład, ale nie widzę, jak mogę go zmapować do mojego problemu.

Każda pomoc zostanie bardzo doceniona.

góry dzięki

PS: Nie mogę pisać wszystkie linki Chciałbym, ale jestem gotów dostarczyć

+0

Cóż - nie znam się na tych bibliotekach, ale typy nie pasują do siebie. 'pureD :: (LMapDom a s, VectorSpace b s) => b -> a:> b' Tak więc typ' pureD t' to 'Double:> Double', ale c1 oczekuje argumentu' Double'. (Tak mówi błąd) – Oliver

+1

Thx Oliver, też to widziałem, ale już napisałem pytanie.Chodzi o to, że nie mam jasności co do rzeczywistego wyprowadzania, co oznacza, w jaki sposób zmienić moją funkcję, aby pasowała do sygnatury typu. Przyjrzę się bliżej odpowiedzi mnish. – TheMADMAN

Odpowiedz

5

To interesująca biblioteka .. Dziękujemy za udostępnienie. Chociaż nie rozumiem koncepcję biblioteki jeszcze jak o ten kod:

{-# 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)] 

Spróbuj również Gx = trzykrotnie (pureD 0, IDD x (Idd * IDD) x) (co wydaje się reprezentują krzywą (0, x, x^2)).

+1

Cóż, to wygląda bardzo dobrze, dziękuję! Kiedy rozumiem to poprawnie, definiuję moją funkcję typu: ~>, co oznacza, że ​​jest ona do określenia w nieskończoność, ma sens, ponieważ tak powinno być. Rozumiem również znaczenie "zmiennej wyprowadzania". Funkcja eval jest potrzebna do wyodrębnienia wartości w punkcie. Funkcja idD oznacza, że ​​może wystąpić wyprowadzenie w tym miejscu. Jak działa "diff"? Myślę, że źle rozumiem znaczenie podstawy, podstawą w R³ jest np. ((1,0,0), (0,1,0), (0,0,1)), ale to nie znaczy, co oznacza biblioteka. W każdym razie bardzo mi pomogłeś! jeszcze raz dziękuję – TheMADMAN

+1

Nie ma za co. Wydaje mi się, że "podstawa" stanowi podstawę przestrzeni stycznej, która w tym przypadku jest podwójna. Jest reprezentowany jako(), ponieważ jest jednowymiarowy. Jeśli przestrzeń styczna jest dwuwymiarowa, "podstawa" jest reprezentowana przez jedną()(), przestrzeń dwupunktową. – mnish

+0

Ok, teraz jest jasne. Jestem teraz w stanie kopać do biblioteki teraz i stosować ją do moich potrzeb. Kiedy mam dalsze pytania, wiem, kogo zapytać :) – TheMADMAN

0

Możesz chcieć wypróbować pakiet ad, który dokłada wszelkich starań, aby ułatwić automatyczne różnicowanie funkcji zapisanych w przezroczystym, idiomatycznym języku 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] 
Powiązane problemy