Quando si utilizza il pacchetto vector-space per le torri derivative (vedere derivative towers), ho riscontrato la necessità di differenziare gli integrali. dalla matematica è del tutto chiaro come raggiungere questo obiettivo:Come differenziare gli integrali con la libreria di vettori (haskell)
f(x) = int g(y) dy from 0 to x
con una funzione
g : R -> R
per esempio.
La derivata rispetto a x sarebbe:
f'(x) = g(x)
Ho cercato di ottenere questo comportamento definendo prima classe "integrazione"
class Integration a b where
--standard integration function
integrate :: (a -> b) -> a -> a -> b
un'istanza di base è
instance Integration Double Double where
integrate f a b = fst $ integrateQAGS prec 1000 f a b
con integrateQAGS
da hmatrix
il problema viene con valori b che rappresentano torri di derivati:
instance Integration Double (Double :> (NC.T Double)) where
integrate = integrateD
NC.T
da Numeric.Complex (numerico-prelude). La funzione integrateD
è definito come segue (ma sbagliato):
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)
La funzione non restituisce quello che voglio, deriva l'integrando, ma non l'integrale. Il problema è che ho bisogno di una mappa lineare che restituisca f u
. Il a :> b
è definito come segue:
data a :> b = D { powVal :: b, derivative :: a :-* (a :> b) }
Non so come definire derivative
. Qualsiasi aiuto sarà apprezzato, grazie
edit:
ho dimenticato di fornire l'istanza per 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
e posso dare un esempio di quello che voglio dire: Diciamo che ho un funzione
f(x) = exp(2*x)*sin(x)
>let f = \x -> (Prelude.exp ((pureD 2.0) AR.* (idD x))) * (sin (idD x)) :: Double :> Double
(AR. *) significa moltiplicazione da Algebra.Anello (numerico-preludio)
posso facilmente integrare questa funzione con la funzione di cui sopra integrateD
:
>integrateD f 0 1 :: Double :> Double
D 1.888605715258933 ...
Quando prendo uno sguardo alla derivata di f:
f'(x) = 2*exp(2*x)*sin(x)+exp(2*x)*cos(x)
e valutare questa a 0
e pi/2
ottengo 1
e qualche valore:
> derivAtBasis (f 0.0)()
D 1.0 ...
> derivAtBasis (f (pi AF./ 2))()
D 46.281385265558534 ...
Ora, quando deriva l'integrale, ottengo la derivazione della funzione f
non il suo valore al limite superiore
> derivAtBasis (integrate f 0 (pi AF./ 2))()
D 46.281385265558534 ...
ma mi aspetto:
> f (pi AF./ 2)
D 23.140692632779267 ...
Sì, è vero. Ma funziona, quando uso la funzione 'powVal' su un valore' Double:> Double'. Ma ovviamente, perdo le informazioni sulla derivata. Devo fornire queste informazioni in modo esplicito, ed è lì che sono bloccato :( – TheMADMAN