2012-02-24 5 views
6

vector-space 패키지에 다시 문제가 있습니다. 나는 최근의 post에서 @mnish로부터 매우 유용한 답을 얻었지만 거기에는 오직 하나의 변수에만 의존하는 함수 만 다루었습니다. 내가있을 때 은 무엇 예를 들어, 두 변수에 따라 달라집니다 데카르트다 변수 함수와 이에 상응하는 벡터 공간 패키지가있는 자코비언의 파생물

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

에 극좌표에서 매핑하는 기능을 발생합니다.

꽤 순진 접근 방식으로,이 밖으로 시도 :

다음과 같은 오류
polar :: Double -> Double -> ((Double,Double) :~> (Double,Double)) 
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, 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)) 

한 구성 요소의

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

Conal의 매우 우아한 자동 차별화 공식의 핵심 한계는 단 하나의 축을 따라 도함수에서만 작동한다는 것입니다. Jacobians 등을 원한다면 ekmett의 광고 패키지가 가장 좋은 방법이라고 생각합니다. http://hackage.haskell.org/package/ad-1.3.0.1 – sclv

+1

감사합니다. @sclv,이 모듈을 살펴본 결과 저는 와우, 나는 감동했다. 나는이 꾸러미를 알아 채지 않고 있었고, 이것을 지적 해 주셔서 감사합니다. – TheMADMAN

+0

당신은 혼자가 아닙니다. 다차원 적 유형이 어떻게 어울리는 지 이해하기 위해 고심하고 있습니다. 나는 'Beautiful Differentiation'이라는 종이를 읽고 빛이 밝혀지기를 희망합니다. 광고 패키지는 유형에 대해 조금 더 단순 해 보입니다! – 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 통해 압축을 풀고 결과 쌍의 첫 번째와 두 번째 부분을 선택해야합니다 (polarxpolary). 둘 다 한 쌍으로 다시 포장됩니다. 어쩌면이 일을하는 더 우아한 방법이 있을지 모르지만, 그것이 내가 그것을 어떻게 이해했는지에 대한 것입니다.

여기에서 원통형 좌표 또는 사실상 다른 곡선 직교 좌표계로 넘어가는 것은 어렵지 않습니다. 원통형 용 내가 구하는 좌표

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 패키지의 좋은 예가 될 것입니다.

나는 아직도 선형지도의 사용과 특히 응용을 찾아야 만한다.

0

이 후속 질문을 보았습니다. 나는 당신이 원하는 것을 확실하지 않다 :

  • 코비안 행렬
  • 코비안 벡터 제품
  • 코비안 - 트랜스 - 벡터 제품 같은 저 차원 시스템에서

, 나는 처음을 추측 할 것이다. (다른 시스템은 주로 시스템이 고차원이므로 자 코비안 당을 저장하거나 계산하지 않고 일반 스파 스 매트릭스로 취급합니다.) 어떤 경우 :

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]] 
관련 문제