2012-02-16 12 views
14

Attualmente sto lavorando con Haskell da un po 'di tempo, ma sono ben lungi dall'essere un esperto. Ma vedo che l'approccio funzionale alla programmazione mi soddisfa al meglio.Derivative Towers e come utilizzare il pacchetto spazio vettoriale (haskell)

Finora sto lavorando a un progetto per calcolare alcune cose serie, come le correnti e i potenziali irradiati da una data struttura.

Ho seguito il blog scritto da Conal Elliott (eccone altri Linear Maps) che è molto bello e fondamentale.

Purtroppo, mi manca un semplice esempio :)

Per essere più precisi, ho una curva

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

che è una semplice linea retta a (0, a, 2 * t) . Quando voglio calcolare la derivata di f, ad es. per la lunghezza della curva, conosco il risultato matematico, che è abbastanza semplice (0,0,2), ma come faccio a farlo in Haskell, specialmente con il pacchetto vector-space?

Ho molta voglia di usare questa libreria per la sua funzionalità, è esattamente l'approccio avrei preso troppo (ma non sono che molto più avanti sulla strada Haskell)

Quello che ho finora è questo :

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

E 'l'effettiva implementazione della funzione pured, fin qui nulla di che ho cercato opere per ottenere questo frammento di codice per compilare. Ottengo il seguente errore:

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. 

C'è anche una libreria grafica che utilizza vector-spazio e c'è anche un esempio su un toro, in cui viene utilizzato pured. Ho cercato di dedurre l'esempio ma non vedo come posso mapparlo al mio problema.

Qualsiasi aiuto sarebbe molto apprezzato.

Grazie in anticipo

PS: non posso postare tutti i link che mi piacerebbe, ma sono disposto a fornire

+0

Bene - Non so molto di queste librerie, ma i tipi non corrispondono. 'pureD :: (LMapDom a s, VectorSpace b s) => b -> a:> b' Quindi il tipo di' pureD t' è 'Double:> Double' ma c1 si aspetta un argomento di' Double'. (Che cosa dice l'errore) – Oliver

+1

Thx Oliver, ho visto anche questo, ma avevo già postato la domanda.Il fatto è, comunque, che non sono chiaro con la derivazione attuale, cioè come cambio la mia funzione in modo che corrisponda alla firma del tipo. Daremo un'occhiata più da vicino alla risposta di mnish. – TheMADMAN

risposta

5

Questo è un'interessante biblioteca .. Grazie per la condivisione. Anche se non capisco il concetto di biblioteca ancora, come su questo codice:

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

Prova anche = gx triplicato (pured 0, IDD x, (IDD * IDD) x) (che sembrano rappresenta la curva (0, x, x^2)).

+1

Beh, sembra molto buono, grazie! Quando capisco correttamente, definisco la mia funzione di tipo: ~>, che significa che è derivabile indefinitamente, ha senso, perché dovrebbe essere così. Capisco anche il significato di "variabile di derivazione", ora. La funzione eval è necessaria per estrarre il valore al punto. La funzione idD indica che può verificarsi una derivazione in questo punto. Come funziona "diff"? Penso di fraintendere il significato della base, una base in R3 è ad es. ((1,0,0), (0,1,0), (0,0,1)), ma questo non è ciò che la libreria significa. In ogni caso, mi hai aiutato molto! grazie ancora – TheMADMAN

+1

Prego. Mi sembra che la "base" rappresenti la base dello spazio tangente, che in questo caso è Double. È rappresentato come() perché è unidimensionale. Se lo spazio tangente è bidimensionale, la "base" è rappresentata da Either()(), lo spazio dei due punti. – mnish

+0

Ok, questo è chiaro ora. Ora sono in grado di scavare più facilmente nella biblioteca e applicarlo alle mie esigenze. Quando ho ulteriori domande, so chi chiedere :) – TheMADMAN

0

Si potrebbe provare il pacchetto ad, che fa del suo meglio per semplificare la differenziazione automatica delle funzioni scritte in Haskell idiomatico trasparente.

$ 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] 
Problemi correlati