summaryrefslogtreecommitdiff
path: root/packages/base/src/Internal/LAPACK.hs
diff options
context:
space:
mode:
authorAlberto Ruiz <aruiz@um.es>2015-06-29 16:37:51 +0200
committerAlberto Ruiz <aruiz@um.es>2015-06-29 16:37:51 +0200
commit9c05df0cd663bafaf0b69eafee53fce45569dc95 (patch)
treebd0dd147c0e099ad6b38e0756461d721b2610f6a /packages/base/src/Internal/LAPACK.hs
parentb1f65d9d3c563350ac0c620ec5cabcf03cff317a (diff)
pass copied slice in linearSolve
Diffstat (limited to 'packages/base/src/Internal/LAPACK.hs')
-rw-r--r--packages/base/src/Internal/LAPACK.hs74
1 files changed, 46 insertions, 28 deletions
diff --git a/packages/base/src/Internal/LAPACK.hs b/packages/base/src/Internal/LAPACK.hs
index c91cddd..13340f2 100644
--- a/packages/base/src/Internal/LAPACK.hs
+++ b/packages/base/src/Internal/LAPACK.hs
@@ -349,57 +349,75 @@ eigOnlyH = vrev . fst. eigSHAux (zheev 0) "eigH'"
349vrev = flatten . flipud . reshape 1 349vrev = flatten . flipud . reshape 1
350 350
351----------------------------------------------------------------------------- 351-----------------------------------------------------------------------------
352foreign import ccall unsafe "linearSolveR_l" dgesv :: TMMM R 352foreign import ccall unsafe "linearSolveR_l" dgesv :: R ::> R ::> Ok
353foreign import ccall unsafe "linearSolveC_l" zgesv :: TMMM C 353foreign import ccall unsafe "linearSolveC_l" zgesv :: C ::> C ::> Ok
354foreign import ccall unsafe "cholSolveR_l" dpotrs :: TMMM R
355foreign import ccall unsafe "cholSolveC_l" zpotrs :: TMMM C
356 354
357linearSolveSQAux g f st a b 355linearSolveSQAux g f st a b
358 | n1==n2 && n1==r = unsafePerformIO . g $ do 356 | n1==n2 && n1==r = unsafePerformIO . g $ do
359 s <- createMatrix ColumnMajor r c 357 a' <- copy ColumnMajor a
360 f # a # b # s #| st 358 s <- copy ColumnMajor b
359 f # a' # s #| st
361 return s 360 return s
362 | otherwise = error $ st ++ " of nonsquare matrix" 361 | otherwise = error $ st ++ " of nonsquare matrix"
363 where 362 where
364 n1 = rows a 363 n1 = rows a
365 n2 = cols a 364 n2 = cols a
366 r = rows b 365 r = rows b
367 c = cols b
368 366
369-- | Solve a real linear system (for square coefficient matrix and several right-hand sides) using the LU decomposition, based on LAPACK's /dgesv/. For underconstrained or overconstrained systems use 'linearSolveLSR' or 'linearSolveSVDR'. See also 'lusR'. 367-- | Solve a real linear system (for square coefficient matrix and several right-hand sides) using the LU decomposition, based on LAPACK's /dgesv/. For underconstrained or overconstrained systems use 'linearSolveLSR' or 'linearSolveSVDR'. See also 'lusR'.
370linearSolveR :: Matrix Double -> Matrix Double -> Matrix Double 368linearSolveR :: Matrix Double -> Matrix Double -> Matrix Double
371linearSolveR a b = linearSolveSQAux id dgesv "linearSolveR" (fmat a) (fmat b) 369linearSolveR a b = linearSolveSQAux id dgesv "linearSolveR" a b
372 370
373mbLinearSolveR :: Matrix Double -> Matrix Double -> Maybe (Matrix Double) 371mbLinearSolveR :: Matrix Double -> Matrix Double -> Maybe (Matrix Double)
374mbLinearSolveR a b = linearSolveSQAux mbCatch dgesv "linearSolveR" (fmat a) (fmat b) 372mbLinearSolveR a b = linearSolveSQAux mbCatch dgesv "linearSolveR" a b
375 373
376 374
377-- | Solve a complex linear system (for square coefficient matrix and several right-hand sides) using the LU decomposition, based on LAPACK's /zgesv/. For underconstrained or overconstrained systems use 'linearSolveLSC' or 'linearSolveSVDC'. See also 'lusC'. 375-- | Solve a complex linear system (for square coefficient matrix and several right-hand sides) using the LU decomposition, based on LAPACK's /zgesv/. For underconstrained or overconstrained systems use 'linearSolveLSC' or 'linearSolveSVDC'. See also 'lusC'.
378linearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) 376linearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double)
379linearSolveC a b = linearSolveSQAux id zgesv "linearSolveC" (fmat a) (fmat b) 377linearSolveC a b = linearSolveSQAux id zgesv "linearSolveC" a b
380 378
381mbLinearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Maybe (Matrix (Complex Double)) 379mbLinearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Maybe (Matrix (Complex Double))
382mbLinearSolveC a b = linearSolveSQAux mbCatch zgesv "linearSolveC" (fmat a) (fmat b) 380mbLinearSolveC a b = linearSolveSQAux mbCatch zgesv "linearSolveC" a b
381
382--------------------------------------------------------------------------------
383foreign import ccall unsafe "cholSolveR_l" dpotrs :: R ::> R ::> Ok
384foreign import ccall unsafe "cholSolveC_l" zpotrs :: C ::> C ::> Ok
385
386
387linearSolveSQAux2 g f st a b
388 | n1==n2 && n1==r = unsafePerformIO . g $ do
389 s <- copy ColumnMajor b
390 f # a # s #| st
391 return s
392 | otherwise = error $ st ++ " of nonsquare matrix"
393 where
394 n1 = rows a
395 n2 = cols a
396 r = rows b
383 397
384-- | Solves a symmetric positive definite system of linear equations using a precomputed Cholesky factorization obtained by 'cholS'. 398-- | Solves a symmetric positive definite system of linear equations using a precomputed Cholesky factorization obtained by 'cholS'.
385cholSolveR :: Matrix Double -> Matrix Double -> Matrix Double 399cholSolveR :: Matrix Double -> Matrix Double -> Matrix Double
386cholSolveR a b = linearSolveSQAux id dpotrs "cholSolveR" (fmat a) (fmat b) 400cholSolveR a b = linearSolveSQAux2 id dpotrs "cholSolveR" (fmat a) b
387 401
388-- | Solves a Hermitian positive definite system of linear equations using a precomputed Cholesky factorization obtained by 'cholH'. 402-- | Solves a Hermitian positive definite system of linear equations using a precomputed Cholesky factorization obtained by 'cholH'.
389cholSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) 403cholSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double)
390cholSolveC a b = linearSolveSQAux id zpotrs "cholSolveC" (fmat a) (fmat b) 404cholSolveC a b = linearSolveSQAux2 id zpotrs "cholSolveC" (fmat a) b
391 405
392----------------------------------------------------------------------------------- 406-----------------------------------------------------------------------------------
393 407
394foreign import ccall unsafe "linearSolveLSR_l" dgels :: TMMM R 408foreign import ccall unsafe "linearSolveLSR_l" dgels :: R ::> R ::> Ok
395foreign import ccall unsafe "linearSolveLSC_l" zgels :: TMMM C 409foreign import ccall unsafe "linearSolveLSC_l" zgels :: C ::> C ::> Ok
396foreign import ccall unsafe "linearSolveSVDR_l" dgelss :: Double -> TMMM R 410foreign import ccall unsafe "linearSolveSVDR_l" dgelss :: Double -> R ::> R ::> Ok
397foreign import ccall unsafe "linearSolveSVDC_l" zgelss :: Double -> TMMM C 411foreign import ccall unsafe "linearSolveSVDC_l" zgelss :: Double -> C ::> C ::> Ok
398 412
399linearSolveAux f st a b = unsafePerformIO $ do 413linearSolveAux f st a b
400 r <- createMatrix ColumnMajor (max m n) nrhs 414 | m == rows b = unsafePerformIO $ do
401 f # a # b # r #| st 415 a' <- copy ColumnMajor a
402 return r 416 r <- createMatrix ColumnMajor (max m n) nrhs
417 setRect 0 0 b r
418 f # a' # r #| st
419 return r
420 | otherwise = error $ "different number of rows in linearSolve ("++st++")"
403 where 421 where
404 m = rows a 422 m = rows a
405 n = cols a 423 n = cols a
@@ -408,12 +426,12 @@ linearSolveAux f st a b = unsafePerformIO $ do
408-- | Least squared error solution of an overconstrained real linear system, or the minimum norm solution of an underconstrained system, using LAPACK's /dgels/. For rank-deficient systems use 'linearSolveSVDR'. 426-- | Least squared error solution of an overconstrained real linear system, or the minimum norm solution of an underconstrained system, using LAPACK's /dgels/. For rank-deficient systems use 'linearSolveSVDR'.
409linearSolveLSR :: Matrix Double -> Matrix Double -> Matrix Double 427linearSolveLSR :: Matrix Double -> Matrix Double -> Matrix Double
410linearSolveLSR a b = subMatrix (0,0) (cols a, cols b) $ 428linearSolveLSR a b = subMatrix (0,0) (cols a, cols b) $
411 linearSolveAux dgels "linearSolverLSR" (fmat a) (fmat b) 429 linearSolveAux dgels "linearSolverLSR" a b
412 430
413-- | Least squared error solution of an overconstrained complex linear system, or the minimum norm solution of an underconstrained system, using LAPACK's /zgels/. For rank-deficient systems use 'linearSolveSVDC'. 431-- | Least squared error solution of an overconstrained complex linear system, or the minimum norm solution of an underconstrained system, using LAPACK's /zgels/. For rank-deficient systems use 'linearSolveSVDC'.
414linearSolveLSC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) 432linearSolveLSC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double)
415linearSolveLSC a b = subMatrix (0,0) (cols a, cols b) $ 433linearSolveLSC a b = subMatrix (0,0) (cols a, cols b) $
416 linearSolveAux zgels "linearSolveLSC" (fmat a) (fmat b) 434 linearSolveAux zgels "linearSolveLSC" a b
417 435
418-- | Minimum norm solution of a general real linear least squares problem Ax=B using the SVD, based on LAPACK's /dgelss/. Admits rank-deficient systems but it is slower than 'linearSolveLSR'. The effective rank of A is determined by treating as zero those singular valures which are less than rcond times the largest singular value. If rcond == Nothing machine precision is used. 436-- | Minimum norm solution of a general real linear least squares problem Ax=B using the SVD, based on LAPACK's /dgelss/. Admits rank-deficient systems but it is slower than 'linearSolveLSR'. The effective rank of A is determined by treating as zero those singular valures which are less than rcond times the largest singular value. If rcond == Nothing machine precision is used.
419linearSolveSVDR :: Maybe Double -- ^ rcond 437linearSolveSVDR :: Maybe Double -- ^ rcond
@@ -421,8 +439,8 @@ linearSolveSVDR :: Maybe Double -- ^ rcond
421 -> Matrix Double -- ^ right hand sides (as columns) 439 -> Matrix Double -- ^ right hand sides (as columns)
422 -> Matrix Double -- ^ solution vectors (as columns) 440 -> Matrix Double -- ^ solution vectors (as columns)
423linearSolveSVDR (Just rcond) a b = subMatrix (0,0) (cols a, cols b) $ 441linearSolveSVDR (Just rcond) a b = subMatrix (0,0) (cols a, cols b) $
424 linearSolveAux (dgelss rcond) "linearSolveSVDR" (fmat a) (fmat b) 442 linearSolveAux (dgelss rcond) "linearSolveSVDR" a b
425linearSolveSVDR Nothing a b = linearSolveSVDR (Just (-1)) (fmat a) (fmat b) 443linearSolveSVDR Nothing a b = linearSolveSVDR (Just (-1)) a b
426 444
427-- | Minimum norm solution of a general complex linear least squares problem Ax=B using the SVD, based on LAPACK's /zgelss/. Admits rank-deficient systems but it is slower than 'linearSolveLSC'. The effective rank of A is determined by treating as zero those singular valures which are less than rcond times the largest singular value. If rcond == Nothing machine precision is used. 445-- | Minimum norm solution of a general complex linear least squares problem Ax=B using the SVD, based on LAPACK's /zgelss/. Admits rank-deficient systems but it is slower than 'linearSolveLSC'. The effective rank of A is determined by treating as zero those singular valures which are less than rcond times the largest singular value. If rcond == Nothing machine precision is used.
428linearSolveSVDC :: Maybe Double -- ^ rcond 446linearSolveSVDC :: Maybe Double -- ^ rcond
@@ -430,8 +448,8 @@ linearSolveSVDC :: Maybe Double -- ^ rcond
430 -> Matrix (Complex Double) -- ^ right hand sides (as columns) 448 -> Matrix (Complex Double) -- ^ right hand sides (as columns)
431 -> Matrix (Complex Double) -- ^ solution vectors (as columns) 449 -> Matrix (Complex Double) -- ^ solution vectors (as columns)
432linearSolveSVDC (Just rcond) a b = subMatrix (0,0) (cols a, cols b) $ 450linearSolveSVDC (Just rcond) a b = subMatrix (0,0) (cols a, cols b) $
433 linearSolveAux (zgelss rcond) "linearSolveSVDC" (fmat a) (fmat b) 451 linearSolveAux (zgelss rcond) "linearSolveSVDC" a b
434linearSolveSVDC Nothing a b = linearSolveSVDC (Just (-1)) (fmat a) (fmat b) 452linearSolveSVDC Nothing a b = linearSolveSVDC (Just (-1)) a b
435 453
436----------------------------------------------------------------------------------- 454-----------------------------------------------------------------------------------
437 455