Haskell 数值前奏曲中的多重积分和矩阵(复数元素)
我需要计算这种形式的积分Haskell 数值前奏曲中的多重积分和矩阵(复数元素),haskell,numerical-analysis,Haskell,Numerical Analysis,我需要计算这种形式的积分 /t /x | P(x)*| P(y) dydx /t0 /t0 其中p是一个函数R->C^(nxn),通常是一个矩阵,我想在Haskell中这样做。我已经为标量函数实现了这一点: import Numeric.GSL.Integration import Data.Complex import Data.List prec :: Double prec = 1E-9 integrate :: (Double -> Double) ->
/t /x
| P(x)*| P(y) dydx
/t0 /t0
其中p是一个函数R->C^(nxn)
,通常是一个矩阵,我想在Haskell中这样做。我已经为标量函数实现了这一点:
import Numeric.GSL.Integration
import Data.Complex
import Data.List
prec :: Double
prec = 1E-9
integrate :: (Double -> Double) -> Double -> Double -> Double
integrate f a b = fst $ integrateQNG prec f a b
integrateC :: (Double -> Complex Double) -> Double -> Double -> Complex Double
integrateC cf a b = (integrate (\x -> realPart (cf x)) a b :+ integrate (\x -> imagPart (cf x)) a b)
multipleIntegration :: Int -> (Double -> Complex Double) -> Double -> (Double -> Complex Double)
multipleIntegration n f a = foldl' (\ acc g' -> (\ x -> integrateC (g'*acc) a x)) (\_ -> 1:+0) (replicate n f)
到目前为止,这是有效的,尽管在n>5时速度相当慢
现在我需要将这个计算扩展到矩阵,我尝试了数字前奏,因为我可以将函数作为矩阵的元素。
我能够积分一个Double->Complex Double
的矩阵,但我在积分中乘以矩阵的实际目标失败了,首先是我的代码:
import MathObj.Matrix as Mat
import Algebra.Ring as AR
import Control.Applicative
import qualified Prelude as P
import Prelude hiding ((*))
import Number.Complex as NC
import Numeric.GSL.Integration
import Data.List
type Complex a = NC.T a
prec :: Double
prec = 1E-9
testMat :: Mat.T (Double -> Complex Double)
testMat = Mat.fromRows 2 2 [[\x-> 0.5 +: 2*x,\y-> cos y +: sin y],[\x-> 0.1*x +:x,\_-> 1 +: 1]]
integrateC :: (Double -> Complex Double) -> Double -> Double -> Complex Double
integrateC cf a b = (integrate (\x -> real (cf x)) a b +: integrate (\x -> imag (cf x)) a b)
integrate :: (Double -> Double) -> Double -> Double -> Double
integrate f a b = fst $ integrateQNG prec f a b
integrateCMat' :: Mat.T (Double -> Complex Double) -> Double -> Mat.T (Double -> Complex Double)
integrateCMat' cmf a = ((\f -> integrateC f a ) <$> cmf)
multipleIntegrationMat :: Int -> Mat.T (Double -> Complex Double) -> Double -> Mat.T (Double -> Complex Double)
multipleIntegrationMat n mf a = integrateCMat' ( testMat * (integrateCMat' testMat a)) a
我知道没有函数乘法的例子。对于这种情况,最好的方法是什么?另一方面,在标量示例中,乘法是有效的,尽管复杂数据类型取自data.complex
。当我使用Number.Complex
尝试标量示例时,我得到了相同的错误
我能做些什么来解决这个问题
谢谢。你可以这样做
integrateCMat':(双精度->材料T(复双精度))
->双人->双人
->材料T(复双)
被积Cmat'cmf a b=Mat.fromRows n m integratedRows
式中(n,m)=材料尺寸(cmf未定义)
integratedCell idx=integratedec(cell函数idx)a b
单元函数idx=(\(Mat.Cons arr)->arr!idx)。cmf
integratedRows=[[integratedCell(i,j)| i
integrateCMat':(双精度->材料T(复双精度))
->双人->双人
->材料T(复双)
被积Cmat'cmf a b=Mat.fromRows n m integratedRows
式中(n,m)=材料尺寸(cmf未定义)
integratedCell idx=integratedec(cell函数idx)a b
单元函数idx=(\(Mat.Cons arr)->arr!idx).cmf
integratedRows=[[integratedCell(i,j)| iPerhaps我遗漏了一些东西,但是……在我看来,你实际上描述了P:(ℝ → ℂ)ⁿˣⁿ, 而不是你的意思,即P:ℝ → ℂⁿˣⁿ.是的,这是真的,我有一个矩阵,这个矩阵包含相同参数的函数,所以数学上是:P:R->C^(nxn)一个参数通过P映射到一个包含复数值的nXn矩阵。在Haskell中,我必须将积分映射到矩阵中,至少这是我的方法,然后我有一个函数矩阵,它依赖于一个实参数。这应该代表数学上下文,我希望如此:)但问题是一样的,我不知何故必须乘以2个函数。好吧,我明白了,你只需在所有矩阵项中输入相同的参数。但这有什么意义,aDouble->Mat.t(复数双精度)
立即解决问题并在概念上更加严格?好吧,当我仔细考虑并尝试正确写入时,应该是:P:R->(R->C)^nxn->C^nxn,我认为这应该是正确的,但我仍然有一个需要积分的函数矩阵,我需要在一段时间后对其应用一个值。我尝试了这个方法,但我对积分有一个问题。当我将积分函数应用于矩阵时,我得到了期望的结果,但是我如何积分:Double->Mat.T(复数双精度)
当库函数只提供对Double->Double
的集成时?也许我遗漏了什么,但是……在我看来,你实际上描述了P:(ℝ → ℂ)ⁿˣⁿ, 而不是你的意思,即P:ℝ → ℂⁿˣⁿ.是的,这是真的,我有一个矩阵,这个矩阵包含相同参数的函数,所以数学上是:P:R->C^(nxn)一个参数通过P映射到一个包含复数值的nXn矩阵。在Haskell中,我必须将积分映射到矩阵中,至少这是我的方法,然后我有一个函数矩阵,它依赖于一个实参数。这应该代表数学上下文,我希望如此:)但问题是一样的,我不知何故必须乘以2个函数。好吧,我明白了,你只需在所有矩阵项中输入相同的参数。但这有什么意义,aDouble->Mat.t(复数双精度)
立即解决问题并在概念上更加严格?好吧,当我仔细考虑并尝试正确写入时,应该是:P:R->(R->C)^nxn->C^nxn,我认为这应该是正确的,但我仍然有一个需要积分的函数矩阵,我需要在一段时间后对其应用一个值。我尝试了这个方法,但我对积分有一个问题。当我将积分函数应用于矩阵时,我得到了期望的结果,但是我如何积分:Double->Mat.T(复杂双精度)
当库函数只提供对Double->Double
的集成时?谢谢你的回答,我尝试了你的代码,并做了一些小的修改(我对Mat.Cons有问题,所以我改为Mat.index,并将列表理解修改为integratedRows=[[integratedCell(I,j))|现在双积分应该是完全直接的,integrateCMat'(\x->integrateCMat'testMat t0x)t0 t
。不是这样吗?的确,这是可行的。但是,我真正需要的是,第一次积分返回一个函数,这个函数再次被输入到积分中,但在积分中与第一次积分的相同矩阵相乘。在我的帖子中,第一行解释起来很复杂:):矩阵函数P(y)
是相对于y
进行积分的,从t0
到x
,即:f(x)=int^x\u t0 P(y)dy
此函数与P(x)
相乘,然后相对于x进行积分:g(t)=int^t\u t0 P(x)*f(x)dx
这个链式积分是乘法积分的一部分,乘法积分是微分方程的通解:d/dty(t)=
matmul.hs:27:59:
No instance for (C (Double -> Complex Double))
arising from a use of `*'
Possible fix:
add an instance declaration for (C (Double -> Complex Double))
In the first argument of `integrateCMat'', namely
`(testMat * (integrateCMat' testMat a))'
In the expression:
integrateCMat' (testMat * (integrateCMat' testMat a)) a
In an equation for `multipleIntegrationMat':
multipleIntegrationMat n mf a
= integrateCMat' (testMat * (integrateCMat' testMat a)) a
Failed, modules loaded: none.
integrateCMat' :: (Double -> Mat.T (Complex Double))
-> Double -> Double
-> Mat.T (Complex Double)
integrateCMat' cmf a b = Mat.fromRows n m integratedRows
where (n,m) = Mat.dimension(cmf undefined)
integratedCell idx = integrateC (cellFunction idx) a b
cellFunction idx = (\(Mat.Cons arr) -> arr ! idx) . cmf
integratedRows = [ [ integratedCell(i,j) | i<-[1..n] ] | j<-[1..m] ]