2012-02-24 9 views
6

के साथ एक बहुविकल्पीय फ़ंक्शन और संबंधित जैकोबियन के व्युत्पन्न मुझे vector-space पैकेज के साथ समस्या हो रही है। मुझे हाल ही में post में @ मिशनी से बहुत उपयोगी उत्तर मिला, लेकिन वहां मैंने केवल एक फ़ंक्शन से निपटाया जो केवल 1 चर पर निर्भर करता है। क्या उदाहरण के लिए, होता है मेरे पास है जब एक समारोह जो cartesiansवेक्टर-स्पेस पैकेज

f:(0,oo) x [0,2pi] -> R² 
(r,phi) -> (r*cos(phi),r*sin(phi)) 

जो 2 चरों पर निर्भर करने के लिए ध्रुवीय निर्देशांक से मैप करता है।

मैं इस बाहर की कोशिश की है, काफी अनुभवहीन दृष्टिकोण के साथ:

polar :: Double -> Double -> ((Double,Double) :~> (Double,Double)) 
polar r phi = \(r,phi) -> (((idD) r)*cos(idD phi),((idD) r)*sin(idD phi)) 

मैं निम्नलिखित त्रुटि मिलती है:

Couldn't match expected type `(Double, Double) :> (Double, Double)' 
      with actual type `(t0, t1)' 
In the expression: 
    (((idD) r) * cos (idD phi), ((idD) r) * sin (idD phi)) 
In the expression: 
    \ (r, phi) 
    -> (((idD) r) * cos (idD phi), ((idD) r) * sin (idD phi)) 
In an equation for `polar': 
    polar r phi 
     = \ (r, phi) 
      -> (((idD) r) * cos (idD phi), ((idD) r) * sin (idD phi)) 

एक घटक के लिए

polarx :: Double -> Double -> ((Double,Double) :~> Double) 
polarx r phi = \(r,phi) -> ((idD) r)*cos(idD phi) 

मैं

मिल
Couldn't match expected type `Double' 
      with actual type `(Double, Double)' 
Expected type: (Double, Double) :> Double 
    Actual type: (Double, Double) :> (Double, Double) 
In the return type of a call of `idD' 
In the first argument of `(*)', namely `((idD) r)' 

जाहिर है कि कुछ प्रकार के विकार हैं, लेकिन मैं यह नहीं समझ सकता कि क्या गलत है।

एक और सवाल उठता है, जब मैं इस तरह के मैपिंग के जैकबियन की गणना करना चाहता हूं। जैसा कि नाम से पता चलता है, इसमें रैखिक मानचित्रों के साथ कुछ करना है, जो निश्चित रूप से पैकेज द्वारा कवर किया गया है, वास्तव में यह उन मानचित्रों पर आधारित है। लेकिन फिर, मेरे हास्केल ज्ञान अपर्याप्त है, मेरे लिए एक समाधान प्राप्त करने के लिए।

+1

मुझे याद है कि कोनल के बहुत ही सुरुचिपूर्ण स्वचालित भेदभाव फॉर्मूलेशन की एक महत्वपूर्ण सीमा यह है कि यह केवल एक अक्ष के साथ डेरिवेटिव पर काम करता है। यदि आप जैकबियन चाहते हैं, आदि, मुझे लगता है कि ekmett का विज्ञापन पैकेज जाने का तरीका है: http://hackage.haskell.org/package/ad-1.3.0.1 – sclv

+1

धन्यवाद @ एससीएलवी, मैंने बस इस मॉड्यूल में देखा और मैं कहना चाहिए, वाह, मैं प्रभावित हूँ। मैंने इस पैकेज को नहीं देखा है और मैं इसे आज़मा दूंगा, – TheMADMAN

+0

को इंगित करने के लिए धन्यवाद, आप अकेले नहीं हैं - मैं यह समझने के लिए संघर्ष कर रहा हूं कि बहु-आयामी प्रकार एक साथ कैसे फिट होते हैं। मैं कागज 'सुंदर भिन्नता' को पढ़ने जा रहा हूं और आशा करता हूं कि यह कुछ प्रकाश डालेगा - विज्ञापन पैकेज प्रकारों पर काफी सरल दिखता है! – Oliver

उत्तर

2

मुझे अंत में मेरी समस्या का हल मिला, यह मुश्किल नहीं था, लेकिन फिर भी मुझे इसे समझने में थोड़ी देर लग गई। यदि कोई और दिलचस्पी लेता है तो मैं विवरण प्रस्तुत करता हूं।

polarCoordD :: ((Double,Double) :~> (Double,Double)) 
polarCoordD = \(r,phi) -> pairD (polarx (r,phi), polary (r,phi)) 
where polarx :: (Double,Double) :~> Double 
     polarx = \(r,phi) -> (fst . unpairD $ (idD) (r,phi))*cos(snd . unpairD $ idD (r, phi)) 
     polary :: (Double,Double) :~> Double 
     polary = \(r,phi) -> (fst . unpairD $ (idD) (r,phi))*sin(snd . unpairD $ idD (r, phi)) 

कुंजी "व्युत्पत्ति चर" टपल (r, phi) जो दो चर मैं फ़र्क करना धारण की (idD) जागरूक बनाना था:

यहां पहली ध्रुवीय मामले के लिए मेरी कोड है। तो मुझे unpairD के माध्यम से टुपल को अनपैक करना होगा और परिणामस्वरूप जोड़ी का पहला और दूसरा भाग (polarx और polary में) चुना होगा। दोनों एक जोड़ी में फिर से पैक कर रहे हैं। शायद ऐसा करने के लिए एक और शानदार तरीका है, लेकिन इस तरह मैं इसे अंत में समझ गया।

यहां से बेलनाकार निर्देशांक या वास्तव में, किसी अन्य घुमावदार ऑर्थोगोनल समन्वय प्रणाली के लिए आगे जाना मुश्किल नहीं है। बेलनाकार के लिए निर्देशांक मैं प्राप्त:

cylCoordD :: (Vec3 Double :~> Vec3 Double) 
cylCoordD = \(r,phi,z) -> tripleD (cylx (r,phi,z), cyly (r,phi,z),cylz (0,0,z)) 
where cylx :: (Double,Double,Double) :~> Double 
     cylx = \(r,phi,z) -> (fst' . untripleD $ (idD) (r,phi,z))*cos(snd' . untripleD $ idD (r, phi,z)) 
     cyly :: (Double,Double,Double) :~> Double 
     cyly = \(r,phi,z) -> (fst' . untripleD $ (idD) (r,phi,z))*sin(snd' . untripleD $ idD (r, phi,z)) 
     cylz :: (Double,Double,Double) :~> Double 
     cylz = \(_,_,z) -> third . untripleD $ idD (0,0,z) 
     fst' :: (a,b,c) -> a 
     fst' (x,_,_) = x 
     snd' :: (a,b,c) -> b 
     snd' (_,y,_) = y 
     third :: (a,b,c) -> c 
     third (_,_,z) = z 

Vec3 Doubletype Vec3 a = (a, a, a) के अंतर्गत आता है जहां। अब हम भी एक परिवर्तन मैट्रिक्स का निर्माण कर सकते हैं:

let transmat = \(r,phi,z) -> powVal $ liftD3 (,,) (normalized $ derivAtBasis (cylCoordD (r,phi,z)) (Left())) (normalized $ derivAtBasis (cylCoordD (r,phi,z)) (Right (Left()))) (normalized $ derivAtBasis (cylCoordD (r,phi,z)) (Right (Right()))) 

*Main> transmat (2, rad 0, 0) 
((1.0,0.0,0.0),(0.0,1.0,0.0),(0.0,0.0,1.0)) 

*Main> transmat (2, rad 90, 0) 
((6.123233995736766e-17,1.0,0.0),(-1.0,6.123233995736766e-17,0.0),(0.0,0.0,1.0)) 

rad एक सुविधा समारोह

rad :: Double -> Double 
rad = (pi*) . (*recip 180) 

अब यह इस Numeric Prelude और/या hmatrix की मैट्रिक्स प्रकार के "मैट्रिक्स" कन्वर्ट करने के लिए दिलचस्प होगा , लेकिन मुझे यकीन नहीं है कि यह भी उपयोगी होगा। लेकिन फिर भी, यह vector-space -package के उपयोग के लिए एक अच्छा उदाहरण होगा।

मुझे अभी भी उपयोग और विशेष रूप से रैखिक मानचित्रों के अनुप्रयोग को समझना है।

0

बस इस अनुवर्ती प्रश्न को देखा। मुझे यकीन है कि आप क्या चाहते हैं नहीं कर रहा हूँ:

  • मैट्रिक्स Jacobian
  • एक Jacobian-वेक्टर उत्पाद
  • एक Jacobian-पक्षांतरित-वेक्टर उत्पाद

इस तरह के एक कम आयामी प्रणाली में, मैं पहले मान लेगा। (अन्य लोग आसानी से काम करते हैं जब सिस्टम उच्च-आयामी पर्याप्त होता है कि आप जैकोबियन प्रति-सी को स्टोर या गणना नहीं करना चाहते हैं, बल्कि इसके बजाय इसे सामान्यीकृत स्पैर मैट्रिक्स के रूप में देखते हैं।) किसी भी मामले में:

Prelude> :m + Numeric.AD 
Prelude Numeric.AD> let f [r,phi] = map (r*) [cos phi, sin phi] 
Prelude Numeric.AD> jacobian f [2,3::Float] 
[[-0.9899925,-0.28224],[0.14112,-1.979985]]