diff options
author | Alberto Ruiz <aruiz@um.es> | 2015-06-29 16:37:51 +0200 |
---|---|---|
committer | Alberto Ruiz <aruiz@um.es> | 2015-06-29 16:37:51 +0200 |
commit | 9c05df0cd663bafaf0b69eafee53fce45569dc95 (patch) | |
tree | bd0dd147c0e099ad6b38e0756461d721b2610f6a /packages/base/src/Internal/LAPACK.hs | |
parent | b1f65d9d3c563350ac0c620ec5cabcf03cff317a (diff) |
pass copied slice in linearSolve
Diffstat (limited to 'packages/base/src/Internal/LAPACK.hs')
-rw-r--r-- | packages/base/src/Internal/LAPACK.hs | 74 |
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'" | |||
349 | vrev = flatten . flipud . reshape 1 | 349 | vrev = flatten . flipud . reshape 1 |
350 | 350 | ||
351 | ----------------------------------------------------------------------------- | 351 | ----------------------------------------------------------------------------- |
352 | foreign import ccall unsafe "linearSolveR_l" dgesv :: TMMM R | 352 | foreign import ccall unsafe "linearSolveR_l" dgesv :: R ::> R ::> Ok |
353 | foreign import ccall unsafe "linearSolveC_l" zgesv :: TMMM C | 353 | foreign import ccall unsafe "linearSolveC_l" zgesv :: C ::> C ::> Ok |
354 | foreign import ccall unsafe "cholSolveR_l" dpotrs :: TMMM R | ||
355 | foreign import ccall unsafe "cholSolveC_l" zpotrs :: TMMM C | ||
356 | 354 | ||
357 | linearSolveSQAux g f st a b | 355 | linearSolveSQAux 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'. |
370 | linearSolveR :: Matrix Double -> Matrix Double -> Matrix Double | 368 | linearSolveR :: Matrix Double -> Matrix Double -> Matrix Double |
371 | linearSolveR a b = linearSolveSQAux id dgesv "linearSolveR" (fmat a) (fmat b) | 369 | linearSolveR a b = linearSolveSQAux id dgesv "linearSolveR" a b |
372 | 370 | ||
373 | mbLinearSolveR :: Matrix Double -> Matrix Double -> Maybe (Matrix Double) | 371 | mbLinearSolveR :: Matrix Double -> Matrix Double -> Maybe (Matrix Double) |
374 | mbLinearSolveR a b = linearSolveSQAux mbCatch dgesv "linearSolveR" (fmat a) (fmat b) | 372 | mbLinearSolveR 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'. |
378 | linearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) | 376 | linearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) |
379 | linearSolveC a b = linearSolveSQAux id zgesv "linearSolveC" (fmat a) (fmat b) | 377 | linearSolveC a b = linearSolveSQAux id zgesv "linearSolveC" a b |
380 | 378 | ||
381 | mbLinearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Maybe (Matrix (Complex Double)) | 379 | mbLinearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Maybe (Matrix (Complex Double)) |
382 | mbLinearSolveC a b = linearSolveSQAux mbCatch zgesv "linearSolveC" (fmat a) (fmat b) | 380 | mbLinearSolveC a b = linearSolveSQAux mbCatch zgesv "linearSolveC" a b |
381 | |||
382 | -------------------------------------------------------------------------------- | ||
383 | foreign import ccall unsafe "cholSolveR_l" dpotrs :: R ::> R ::> Ok | ||
384 | foreign import ccall unsafe "cholSolveC_l" zpotrs :: C ::> C ::> Ok | ||
385 | |||
386 | |||
387 | linearSolveSQAux2 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'. |
385 | cholSolveR :: Matrix Double -> Matrix Double -> Matrix Double | 399 | cholSolveR :: Matrix Double -> Matrix Double -> Matrix Double |
386 | cholSolveR a b = linearSolveSQAux id dpotrs "cholSolveR" (fmat a) (fmat b) | 400 | cholSolveR 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'. |
389 | cholSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) | 403 | cholSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) |
390 | cholSolveC a b = linearSolveSQAux id zpotrs "cholSolveC" (fmat a) (fmat b) | 404 | cholSolveC a b = linearSolveSQAux2 id zpotrs "cholSolveC" (fmat a) b |
391 | 405 | ||
392 | ----------------------------------------------------------------------------------- | 406 | ----------------------------------------------------------------------------------- |
393 | 407 | ||
394 | foreign import ccall unsafe "linearSolveLSR_l" dgels :: TMMM R | 408 | foreign import ccall unsafe "linearSolveLSR_l" dgels :: R ::> R ::> Ok |
395 | foreign import ccall unsafe "linearSolveLSC_l" zgels :: TMMM C | 409 | foreign import ccall unsafe "linearSolveLSC_l" zgels :: C ::> C ::> Ok |
396 | foreign import ccall unsafe "linearSolveSVDR_l" dgelss :: Double -> TMMM R | 410 | foreign import ccall unsafe "linearSolveSVDR_l" dgelss :: Double -> R ::> R ::> Ok |
397 | foreign import ccall unsafe "linearSolveSVDC_l" zgelss :: Double -> TMMM C | 411 | foreign import ccall unsafe "linearSolveSVDC_l" zgelss :: Double -> C ::> C ::> Ok |
398 | 412 | ||
399 | linearSolveAux f st a b = unsafePerformIO $ do | 413 | linearSolveAux 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'. |
409 | linearSolveLSR :: Matrix Double -> Matrix Double -> Matrix Double | 427 | linearSolveLSR :: Matrix Double -> Matrix Double -> Matrix Double |
410 | linearSolveLSR a b = subMatrix (0,0) (cols a, cols b) $ | 428 | linearSolveLSR 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'. |
414 | linearSolveLSC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) | 432 | linearSolveLSC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) |
415 | linearSolveLSC a b = subMatrix (0,0) (cols a, cols b) $ | 433 | linearSolveLSC 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. |
419 | linearSolveSVDR :: Maybe Double -- ^ rcond | 437 | linearSolveSVDR :: 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) |
423 | linearSolveSVDR (Just rcond) a b = subMatrix (0,0) (cols a, cols b) $ | 441 | linearSolveSVDR (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 |
425 | linearSolveSVDR Nothing a b = linearSolveSVDR (Just (-1)) (fmat a) (fmat b) | 443 | linearSolveSVDR 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. |
428 | linearSolveSVDC :: Maybe Double -- ^ rcond | 446 | linearSolveSVDC :: 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) |
432 | linearSolveSVDC (Just rcond) a b = subMatrix (0,0) (cols a, cols b) $ | 450 | linearSolveSVDC (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 |
434 | linearSolveSVDC Nothing a b = linearSolveSVDC (Just (-1)) (fmat a) (fmat b) | 452 | linearSolveSVDC Nothing a b = linearSolveSVDC (Just (-1)) a b |
435 | 453 | ||
436 | ----------------------------------------------------------------------------------- | 454 | ----------------------------------------------------------------------------------- |
437 | 455 | ||