Skip to content

Commit 7316c82

Browse files
authored
[LAPACK] Interface lacpy! and add a Julia version copytrito! (#51909)
The PR adds a function `lacpy!` to easily copy a triangular part of a square or rectangular dense matrix.
1 parent 7f59ef7 commit 7316c82

File tree

5 files changed

+123
-0
lines changed

5 files changed

+123
-0
lines changed

src/LinearAlgebra.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export
7676
cond,
7777
condskeel,
7878
copyto!,
79+
copytrito!,
7980
copy_transpose!,
8081
cross,
8182
adjoint,

src/generic.jl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,3 +1897,48 @@ end
18971897

18981898
normalize(x) = x / norm(x)
18991899
normalize(x, p::Real) = x / norm(x, p)
1900+
1901+
"""
1902+
copytrito!(B, A, uplo) -> B
1903+
1904+
Copies a triangular part of a matrix `A` to another matrix `B`.
1905+
`uplo` specifies the part of the matrix `A` to be copied to `B`.
1906+
Set `uplo = 'L'` for the lower triangular part or `uplo = 'U'
1907+
for the upper triangular part.
1908+
1909+
!!! compat "Julia 1.11"
1910+
`copytrito!` requires at least Julia 1.11.
1911+
1912+
# Examples
1913+
```jldoctest
1914+
julia> A = [1 2 ; 3 4];
1915+
1916+
julia> B = [0 0 ; 0 0];
1917+
1918+
julia> copytrito!(B, A, 'L')
1919+
2×2 Matrix{Int64}:
1920+
1 0
1921+
3 4
1922+
```
1923+
"""
1924+
function copytrito!(B::AbstractMatrix, A::AbstractMatrix, uplo::AbstractChar)
1925+
require_one_based_indexing(A, B)
1926+
BLAS.chkuplo(uplo)
1927+
m,n = size(A)
1928+
m1,n1 = size(B)
1929+
(m1 < m || n1 < n) && throw(DimensionMismatch("B of size ($m1,$n1) should have at least the same number of rows and columns than A of size ($m,$n)"))
1930+
if uplo == 'U'
1931+
for j=1:n
1932+
for i=1:min(j,m)
1933+
@inbounds B[i,j] = A[i,j]
1934+
end
1935+
end
1936+
else # uplo == 'L'
1937+
for j=1:n
1938+
for i=j:m
1939+
@inbounds B[i,j] = A[i,j]
1940+
end
1941+
end
1942+
end
1943+
return B
1944+
end

src/lapack.jl

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6992,4 +6992,57 @@ Returns `X` (overwriting `C`) and `scale`.
69926992
"""
69936993
trsyl!(transa::AbstractChar, transb::AbstractChar, A::AbstractMatrix, B::AbstractMatrix, C::AbstractMatrix, isgn::Int=1)
69946994

6995+
for (fn, elty) in ((:dlacpy_, :Float64),
6996+
(:slacpy_, :Float32),
6997+
(:zlacpy_, :ComplexF64),
6998+
(:clacpy_, :ComplexF32))
6999+
@eval begin
7000+
# SUBROUTINE DLACPY( UPLO, M, N, A, LDA, B, LDB )
7001+
# .. Scalar Arguments ..
7002+
# CHARACTER UPLO
7003+
# INTEGER LDA, LDB, M, N
7004+
# ..
7005+
# .. Array Arguments ..
7006+
# DOUBLE PRECISION A( LDA, * ), B( LDB, * )
7007+
# ..
7008+
function lacpy!(B::AbstractMatrix{$elty}, A::AbstractMatrix{$elty}, uplo::AbstractChar)
7009+
require_one_based_indexing(A, B)
7010+
chkstride1(A, B)
7011+
m,n = size(A)
7012+
m1,n1 = size(B)
7013+
(m1 < m || n1 < n) && throw(DimensionMismatch("B of size ($m1,$n1) should have at least the same number of rows and columns than A of size ($m,$n)"))
7014+
lda = max(1, stride(A, 2))
7015+
ldb = max(1, stride(B, 2))
7016+
ccall((@blasfunc($fn), libblastrampoline), Cvoid,
7017+
(Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt}, Ptr{$elty},
7018+
Ref{BlasInt}, Ptr{$elty}, Ref{BlasInt}, Clong),
7019+
uplo, m, n, A, lda, B, ldb, 1)
7020+
B
7021+
end
7022+
end
7023+
end
7024+
7025+
"""
7026+
lacpy!(B, A, uplo) -> B
7027+
7028+
Copies all or part of a matrix `A` to another matrix `B`.
7029+
uplo specifies the part of the matrix `A` to be copied to `B`.
7030+
Set `uplo = 'L'` for the lower triangular part, `uplo = 'U'`
7031+
for the upper triangular part, any other character for all
7032+
the matrix `A`.
7033+
7034+
# Examples
7035+
```jldoctest
7036+
julia> A = [1. 2. ; 3. 4.];
7037+
7038+
julia> B = [0. 0. ; 0. 0.];
7039+
7040+
julia> LAPACK.lacpy!(B, A, 'U')
7041+
2×2 Matrix{Float64}:
7042+
1.0 2.0
7043+
0.0 4.0
7044+
```
7045+
"""
7046+
lacpy!(B::AbstractMatrix, A::AbstractMatrix, uplo::AbstractChar)
7047+
69957048
end # module

test/generic.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,4 +636,15 @@ end
636636
@test condskeel(A) condskeel(A, [8,8,8])
637637
end
638638

639+
@testset "copytrito!" begin
640+
n = 10
641+
A = rand(n, n)
642+
for uplo in ('L', 'U')
643+
B = zeros(n, n)
644+
copytrito!(B, A, uplo)
645+
C = uplo == 'L' ? tril(A) : triu(A)
646+
@test B C
647+
end
648+
end
649+
639650
end # module TestGeneric

test/lapack.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,19 @@ end
685685
end
686686
end
687687

688+
@testset "lacpy!" begin
689+
@testset for elty in (Float32, Float64, ComplexF32, ComplexF64)
690+
n = 10
691+
A = rand(elty, n, n)
692+
for uplo in ('L', 'U', 'N')
693+
B = zeros(elty, n, n)
694+
LinearAlgebra.LAPACK.lacpy!(B, A, uplo)
695+
C = uplo == 'L' ? tril(A) : (uplo == 'U' ? triu(A) : A)
696+
@test B C
697+
end
698+
end
699+
end
700+
688701
@testset "Julia vs LAPACK" begin
689702
# Test our own linear algebra functionality against LAPACK
690703
@testset for elty in (Float32, Float64, ComplexF32, ComplexF64)

0 commit comments

Comments
 (0)