Podczas korzystania z pakietu vector-space dla wież pochodnych (patrz derivative towers), natknąłem się na potrzebę różnicowania całek. Z matematyką jest całkiem jasne, jak to osiągnąć:Jak rozróżnić całki z biblioteką przestrzeni wektorowej (haskell)
f(x) = int g(y) dy from 0 to x
z funkcją
g : R -> R
na przykład.
Pochodna względem x byłoby:
f'(x) = g(x)
Próbowałem dostać ten problem, najpierw zdefiniować klasę "integracja"
class Integration a b where
--standard integration function
integrate :: (a -> b) -> a -> a -> b
podstawowym instancji jest
instance Integration Double Double where
integrate f a b = fst $ integrateQAGS prec 1000 f a b
z integrateQAGS
z hmatrix
problem jest związany z wartościami B, które stanowią wieże pochodnych:
instance Integration Double (Double :> (NC.T Double)) where
integrate = integrateD
NC.T
wynosi od Numeric.Complex (numerycznych-wstęp). Funkcja integrateD
jest zdefiniowana w następujący sposób (ale źle):
integrateD ::(Integration a b, HasTrie (Basis a), HasBasis a, AdditiveGroup b) => (a -> a :> b) -> a -> a -> (a :> b)
integrateD f l u = D (integrate (powVal . f) l u) (derivative $ f u)
Funkcja nie zwraca to, co chcę, to wywodzi się całki, ale nie całki. Problem polega na tym, że potrzebuję liniowej mapy, która zwraca f u
. a :> b
jest zdefiniowany następująco:
data a :> b = D { powVal :: b, derivative :: a :-* (a :> b) }
nie wiem jak zdefiniować derivative
. Każda pomoc będzie mile widziane, dzięki
edit:
zapomniałem podać instancję Integration Double (NC.T Double)
:
instance Integration Double (NC.T Double) where
integrate f a b = bc $ (\g -> integrate g a b) <$> [NC.real . f, NC.imag . f]
where bc (x:y:[]) = x NC.+: y
i mogę dać przykład, co mam na myśli: Powiedzmy mam funkcja
f(x) = exp(2*x)*sin(x)
>let f = \x -> (Prelude.exp ((pureD 2.0) AR.* (idD x))) * (sin (idD x)) :: Double :> Double
(AR. *) oznacza mnożenie z algebry.Pierścień (numeryczna-wstępem)
można łatwo zintegrować z tej funkcji w wyżej funkcji integrateD
:
>integrateD f 0 1 :: Double :> Double
D 1.888605715258933 ...
Gdy spojrzeć na pochodnej f:
f'(x) = 2*exp(2*x)*sin(x)+exp(2*x)*cos(x)
i oceny tej pod numerami: 0
i pi/2
Otrzymuję 1
i niektóre wartości:
> derivAtBasis (f 0.0)()
D 1.0 ...
> derivAtBasis (f (pi AF./ 2))()
D 46.281385265558534 ...
Teraz, kiedy pochodzący całki, otrzymuję wyprowadzenie funkcji f
nie jej wartość w górnej granicy
> derivAtBasis (integrate f 0 (pi AF./ 2))()
D 46.281385265558534 ...
Ale spodziewam:
> f (pi AF./ 2)
D 23.140692632779267 ...
Tak, to prawda. Ale działa, gdy używam funkcji 'powVal' na wartości' Double:> Double'. Ale oczywiście tracę informacje o pochodnej. Muszę wyraźnie przekazać te informacje i to tam utknąłem :( – TheMADMAN