2012-07-11 13 views
5

के साथ इंटीग्रल को अलग करने के लिए कैसे करें व्युत्पन्न टावरों के लिए vector-space पैकेज का उपयोग करते समय (derivative towers देखें) मैं इंटीग्रल को अलग करने की आवश्यकता को पूरा करता हूं। एक समारोहवेक्टर-स्पेस लाइब्रेरी (हैकसेल)

g : R -> R 
उदाहरण के लिए

साथ

f(x) = int g(y) dy from 0 to x 

: गणित से यह कैसे इस लक्ष्य को हासिल करने के लिए काफी स्पष्ट है।

एक्स के संबंध में व्युत्पन्न होगा:

f'(x) = g(x) 

मैं पहली बार एक वर्ग "एकता" को परिभाषित करते हुए इस व्यवहार प्राप्त करने की कोशिश

class Integration a b where 
--standard integration function 
integrate :: (a -> b) -> a -> a -> b 

एक बुनियादी उदाहरण

instance Integration Double Double where 
    integrate f a b = fst $ integrateQAGS prec 1000 f a b 
है

integrateQAGShmatrix

से

instance Integration Double (Double :> (NC.T Double)) where 
    integrate = integrateD 

NC.T Numeric.Complex (संख्यात्मक-प्रस्तावना) से है:

समस्या मान ख जो डेरिवेटिव के टावरों का प्रतिनिधित्व करते हैं के साथ आता है। समारोह integrateD इस प्रकार परिभाषित किया गया है (लेकिन गलत):

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) 

समारोह वापस नहीं करता है मैं क्या चाहते हैं, यह integrand निकला है, लेकिन अभिन्न नहीं। समस्या यह है कि मुझे एक रैखिक मानचित्र की आवश्यकता है जो f u लौटाता है।

data a :> b = D { powVal :: b, derivative :: a :-* (a :> b) } 

मैं कैसे derivative परिभाषित करने के लिए पता नहीं है: इस प्रकार a :> b परिभाषित किया गया है। किसी भी मदद की सराहना की जाएगी, धन्यवाद

संपादित करें:

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 

और मुझे लगता है मैं क्या मतलब का एक उदाहरण दे सकते हैं: चलो कहते हैं कि मैं एक करते हैं

मैं Integration Double (NC.T Double) के लिए उदाहरण प्रदान करने के लिए भूल गया फंक्शन

f(x) = exp(2*x)*sin(x) 

>let f = \x -> (Prelude.exp ((pureD 2.0) AR.* (idD x))) * (sin (idD x)) :: Double :> Double 

(एआर। *) का अर्थ बीजगणित से गुणा है।अंगूठी (संख्यात्मक-प्रस्तावना)

मैं आसानी से ऊपर समारोह integrateD के साथ इस समारोह को एकीकृत कर सकते हैं:

>integrateD f 0 1 :: Double :> Double 
D 1.888605715258933 ... 

जब मैं च के व्युत्पन्न पर एक नज़र डालें:

f'(x) = 2*exp(2*x)*sin(x)+exp(2*x)*cos(x) 

और इस का मूल्यांकन

> derivAtBasis (f 0.0)() 
D 1.0 ... 

> derivAtBasis (f (pi AF./ 2))() 
D 46.281385265558534 ... 
: 0 और pi/2 पर मैं 1 और कुछ मूल्य प्राप्त

अब, जब अभिन्न पाने, मैं समारोह f की व्युत्पत्ति नहीं ऊपरी बाध्य

> derivAtBasis (integrate f 0 (pi AF./ 2))() 
D 46.281385265558534 ... 

पर अपने मूल्य लेकिन मैं उम्मीद:

> f (pi AF./ 2) 
D 23.140692632779267 ... 

उत्तर

0

मुझे अंत में मेरे प्रश्न का समाधान मिला। समाधान की कुंजी वेक्टर-स्पेस पैकेज से >-< फ़ंक्शन है, यह श्रृंखला नियम के लिए है।

तो, मैं इस तरह एक समारोह integrateD' को परिभाषित:

integrateD' :: (Integration a b, HasTrie (Basis a), HasBasis a, AdditiveGroup b , b ~ Scalar b, VectorSpace b) => (a -> a :> b) -> a -> a -> (a:>b) -> (a :> b) 
integrateD' f l u d_one = ((\_ -> integrate (powVal . f) l (u)) >-< (\_ -> f u)) (d_one) 

d_one का मतलब है एक व्युत्पत्ति चर और उसके व्युत्पन्न 1. इस समारोह के साथ होना चाहिए मैं अब

instance Integration Double (Double :> Double) where 
integrate f l u = integrateD' f l u (idD 1) 
जैसे कुछ उदाहरण बना सकते हैं

और

instance Integration (Double) (Double :> (NC.T Double)) where 
integrate f l u = liftD2 (NC.+:) (integrateD' (\x -> NC.real <$>> f x) l u (idD 1.0 :: Double :> Double)) (integrateD' (\x -> NC.imag <$>> f x) l u (idD 1.0 :: Double :> Double)) 

दुर्भाग्य से मैं integrateD का उपयोग बॉक्स के जटिल मूल्यों पर नहीं कर सकता, मुझे liftD2 का उपयोग करना है। ऐसा लगता है कि idD फ़ंक्शन लगता है, मुझे नहीं पता कि एक और अधिक शानदार समाधान है या नहीं।

*Main> derivAtBasis (integrateD' f 0 (pi AF./ 2) (idD 1.0 :: Double :> Double))() 
D 23.140692632779267 ... 

या उदाहरण का उपयोग करते हुए:

मैं विचाराधीन उदाहरण देखें, अब मैं अपनी वांछित समाधान प्राप्त

*Main> derivAtBasis (integrate f 0 (pi AF./ 2))() 
D 23.140692632779267 ... 
0

'hmatrix' के लिए बहुत बारीकी से जुड़ा हुआ है डबल। आप अपने कार्यों का उपयोग अन्य संख्यात्मक डेटा प्रकारों जैसे 'वेक्टर-स्पेस' या 'विज्ञापन' द्वारा प्रदान नहीं कर सकते हैं।

+0

हाँ यह सच है। लेकिन यह काम करता है, जब मैं 'डबल:> डबल' मान पर 'पावल' फ़ंक्शन का उपयोग करता हूं। लेकिन निश्चित रूप से, मैं व्युत्पन्न के बारे में जानकारी खो देता हूं। मुझे यह जानकारी स्पष्ट रूप से प्रदान करनी है, और यही वह जगह है जहां मैं अटक गया हूं :( – TheMADMAN

1

तुम सिर्फ एक पर ई करना चाहते हैं तो फ़ंक्शन जिसमें संख्यात्मक एकीकरण शामिल है, एडी सिस्टम के बिना एकीकरण प्रति-से के बारे में जानने के बिना, इसे "बस काम करना चाहिए"। यहाँ एक उदाहरण है। (इस एकीकरण दिनचर्या बहुत भावुक इसलिए नाम है।)

import Numeric.AD 
import Data.Complex 

intIcky :: (Integral a, Fractional b) => a -> (b -> b) -> b -> b -> b 
intIcky n f a b = c/n' * sum [f (a+fromIntegral i*c/(n'-1)) | i<-[0..n-1]] 
    where n' = fromIntegral n 
     c = b-a 

sinIcky t = intIcky 1000 cos 0 t 
cosIcky t = diff sinIcky t 

test1 = map sinIcky [0,pi/2..2*pi::Float] 
-- [0.0,0.9997853,-4.4734867e-7,-0.9966421,6.282018e-3] 
test2 = map sin [0,pi/2..2*pi::Float] 
-- [0.0,1.0,-8.742278e-8,-1.0,-3.019916e-7] 
test3 = map cosIcky [0,pi/2..2*pi::Float] 
-- [1.0,-2.8568506e-4,-0.998999,2.857402e-3,0.999997] 
test4 = map cos [0,pi/2..2*pi::Float] 
-- [1.0,-4.371139e-8,-1.0,1.1924881e-8,1.0] 
test5 = diffs sinIcky (2*pi::Float) 
-- [6.282019e-3,0.99999696,-3.143549e-3,-1.0004976,3.1454563e-3,1.0014982,-3.1479746e-3,...] 
test6 = diffs sinIcky (2*pi::Complex Float) 
-- [6.282019e-3 :+ 0.0,0.99999696 :+ 0.0,(-3.143549e-3) :+ 0.0,(-1.0004976) :+ 0.0,...] 

केवल चेतावनियां कि सांख्यिक एकीकरण दिनचर्या ई के साथ अच्छी तरह से खेलने के लिए, और भी जटिल तर्क को स्वीकार जरूरत होती है।और भी अधिक अनुभवहीन कुछ, जैसे

intIcky' dx f x0 x1 = dx * sum [f x|x<-[x0,x0+dx..x1]] 

, एकीकरण की ऊपरी सीमा में piecewise स्थिर है Enum और इसलिए गैर जटिल होने के लिए एकीकरण की सीमा की आवश्यकता है, और यह भी अक्सर दी गई सीमा के बाहर integrand इस की वजह से मूल्यांकन करता है :

Prelude> last [0..9.5] 
10.0 
संबंधित मुद्दे