178
178
parent (A:: UpperOrLowerTriangular ) = A. data
179
179
180
180
# For strided matrices, we may only loop over the filled triangle
181
- copy (A:: UpperOrLowerTriangular{<:Any, <:StridedMaybeAdjOrTransMat} ) = copyto ! (similar (A), A)
181
+ copy (A:: UpperOrLowerTriangular{<:Any, <:StridedMaybeAdjOrTransMat} ) = copy ! (similar (A), A)
182
182
183
183
# then handle all methods that requires specific handling of upper/lower and unit diagonal
184
184
@@ -532,30 +532,34 @@ for T in (:UpperOrUnitUpperTriangular, :LowerOrUnitLowerTriangular)
532
532
if axes (dest) != axes (U)
533
533
@invoke copyto! (dest:: AbstractArray , U:: AbstractArray )
534
534
else
535
- _copyto ! (dest, U)
535
+ copy ! (dest, U)
536
536
end
537
537
return dest
538
538
end
539
+ @eval function copy! (dest:: $T , U:: $T )
540
+ axes (dest) == axes (U) || throw (ArgumentError (
541
+ " arrays must have the same axes for copy! (consider using `copyto!`)" ))
542
+ _copy! (dest, U)
543
+ end
539
544
end
540
545
541
546
# copy and scale
542
547
for (T, UT) in ((:UpperTriangular , :UnitUpperTriangular ), (:LowerTriangular , :UnitLowerTriangular ))
543
- @eval @inline function _copyto! (A:: $T , B:: $T )
544
- @boundscheck checkbounds (A, axes (B)... )
548
+ @eval @inline function _copy! (A:: $T , B:: $T )
545
549
copytrito! (parent (A), parent (B), uplo_char (A))
546
550
return A
547
551
end
548
- @eval @inline function _copyto ! (A:: $UT , B:: $T )
552
+ @eval @inline function _copy ! (A:: $UT , B:: $T )
549
553
for dind in diagind (A, IndexStyle (A))
550
554
if A[dind] != B[dind]
551
555
throw_nononeerror (typeof (A), B[dind], Tuple (dind)... )
552
556
end
553
557
end
554
- _copyto ! ($ T (parent (A)), B)
558
+ _copy ! ($ T (parent (A)), B)
555
559
return A
556
560
end
557
561
end
558
- @inline function _copyto ! (A:: UpperOrUnitUpperTriangular , B:: UnitUpperTriangular )
562
+ @inline function _copy ! (A:: UpperOrUnitUpperTriangular , B:: UnitUpperTriangular )
559
563
@boundscheck checkbounds (A, axes (B)... )
560
564
B2 = Base. unalias (A, B)
561
565
Ap = parent (A)
570
574
end
571
575
return A
572
576
end
573
- @inline function _copyto ! (A:: LowerOrUnitLowerTriangular , B:: UnitLowerTriangular )
577
+ @inline function _copy ! (A:: LowerOrUnitLowerTriangular , B:: UnitLowerTriangular )
574
578
@boundscheck checkbounds (A, axes (B)... )
575
579
B2 = Base. unalias (A, B)
576
580
Ap = parent (A)
@@ -595,23 +599,30 @@ _triangularize!(::LowerOrUnitLowerTriangular) = tril!
595
599
if axes (dest) != axes (U)
596
600
@invoke copyto! (dest:: StridedMatrix , U:: AbstractArray )
597
601
else
598
- _copyto ! (dest, U)
602
+ copy ! (dest, U)
599
603
end
600
604
return dest
601
605
end
602
- @propagate_inbounds function _copyto! (dest:: StridedMatrix , U:: UpperOrLowerTriangular )
606
+
607
+ function copy! (dest:: StridedMatrix , U:: UpperOrLowerTriangular )
608
+ axes (dest) == axes (U) || throw (ArgumentError (
609
+ " arrays must have the same axes for copy! (consider using `copyto!`)" ))
610
+ _copy! (dest, U)
611
+ end
612
+
613
+ @propagate_inbounds function _copy! (dest:: StridedMatrix , U:: UpperOrLowerTriangular )
603
614
copytrito! (dest, parent (U), U isa UpperOrUnitUpperTriangular ? ' U' : ' L' )
604
615
copytrito! (dest, U, U isa UpperOrUnitUpperTriangular ? ' L' : ' U' )
605
616
return dest
606
617
end
607
- @propagate_inbounds function _copyto ! (dest:: StridedMatrix , U:: UpperOrLowerTriangular{<:Any, <:StridedMatrix} )
618
+ @propagate_inbounds function _copy ! (dest:: StridedMatrix , U:: UpperOrLowerTriangular{<:Any, <:StridedMatrix} )
608
619
U2 = Base. unalias (dest, U)
609
- copyto_unaliased ! (dest, U2)
620
+ copy_unaliased ! (dest, U2)
610
621
return dest
611
622
end
612
623
# for strided matrices, we explicitly loop over the arrays to improve cache locality
613
624
# This fuses the copytrito! for the two halves
614
- @inline function copyto_unaliased ! (dest:: StridedMatrix , U:: UpperOrUnitUpperTriangular{<:Any, <:StridedMatrix} )
625
+ @inline function copy_unaliased ! (dest:: StridedMatrix , U:: UpperOrUnitUpperTriangular{<:Any, <:StridedMatrix} )
615
626
@boundscheck checkbounds (dest, axes (U)... )
616
627
isunit = U isa UnitUpperTriangular
617
628
for col in axes (dest,2 )
624
635
end
625
636
return dest
626
637
end
627
- @inline function copyto_unaliased ! (dest:: StridedMatrix , L:: LowerOrUnitLowerTriangular{<:Any, <:StridedMatrix} )
638
+ @inline function copy_unaliased ! (dest:: StridedMatrix , L:: LowerOrUnitLowerTriangular{<:Any, <:StridedMatrix} )
628
639
@boundscheck checkbounds (dest, axes (L)... )
629
640
isunit = L isa UnitLowerTriangular
630
641
for col in axes (dest,2 )
@@ -645,7 +656,7 @@ Base.@constprop :aggressive function copytrito_triangular!(Bdata, Adata, uplo, u
645
656
BLAS. chkuplo (uplo)
646
657
LAPACK. lacpy_size_check (size (Bdata), sz)
647
658
# only the diagonal is copied in this case
648
- copyto ! (diagview (Bdata), diagview (Adata))
659
+ copy ! (diagview (Bdata), diagview (Adata))
649
660
end
650
661
return Bdata
651
662
end
@@ -1055,15 +1066,17 @@ isunit_char(::UnitUpperTriangular) = 'U'
1055
1066
isunit_char (:: LowerTriangular ) = ' N'
1056
1067
isunit_char (:: UnitLowerTriangular ) = ' U'
1057
1068
1069
+ _copy_or_copyto! (dest, src) = ndims (dest) == ndims (src) ? copy! (dest, src) : copyto! (dest, src)
1070
+
1058
1071
# generic fallback for AbstractTriangular matrices outside of the four subtypes provided here
1059
1072
_trimul! (C:: AbstractVecOrMat , A:: AbstractTriangular , B:: AbstractVector ) =
1060
- lmul! (A, copyto ! (C, B))
1073
+ lmul! (A, _copy_or_copyto ! (C, B))
1061
1074
_trimul! (C:: AbstractMatrix , A:: AbstractTriangular , B:: AbstractMatrix ) =
1062
- lmul! (A, copyto ! (C, B))
1075
+ lmul! (A, copy ! (C, B))
1063
1076
_trimul! (C:: AbstractMatrix , A:: AbstractMatrix , B:: AbstractTriangular ) =
1064
- rmul! (copyto ! (C, A), B)
1077
+ rmul! (copy ! (C, A), B)
1065
1078
_trimul! (C:: AbstractMatrix , A:: AbstractTriangular , B:: AbstractTriangular ) =
1066
- lmul! (A, copyto ! (C, B))
1079
+ lmul! (A, copy ! (C, B))
1067
1080
# redirect for UpperOrLowerTriangular
1068
1081
_trimul! (C:: AbstractVecOrMat , A:: UpperOrLowerTriangular , B:: AbstractVector ) =
1069
1082
generic_trimatmul! (C, uplo_char (A), isunit_char (A), wrapperop (parent (A)), _unwrap_at (parent (A)), B)
@@ -1124,9 +1137,9 @@ end
1124
1137
ldiv! (C:: AbstractVecOrMat , A:: AbstractTriangular , B:: AbstractVecOrMat ) = _ldiv! (C, A, B)
1125
1138
# generic fallback for AbstractTriangular, directs to 2-arg [l/r]div!
1126
1139
_ldiv! (C:: AbstractVecOrMat , A:: AbstractTriangular , B:: AbstractVecOrMat ) =
1127
- ldiv! (A, copyto ! (C, B))
1140
+ ldiv! (A, _copy_or_copyto ! (C, B))
1128
1141
_rdiv! (C:: AbstractMatrix , A:: AbstractMatrix , B:: AbstractTriangular ) =
1129
- rdiv! (copyto ! (C, A), B)
1142
+ rdiv! (copy ! (C, A), B)
1130
1143
# redirect for UpperOrLowerTriangular to generic_*div!
1131
1144
_ldiv! (C:: AbstractVecOrMat , A:: UpperOrLowerTriangular , B:: AbstractVecOrMat ) =
1132
1145
generic_trimatdiv! (C, uplo_char (A), isunit_char (A), wrapperop (parent (A)), _unwrap_at (parent (A)), B)
@@ -1204,40 +1217,40 @@ for (t, uploc, isunitc) in ((:LowerTriangular, 'L', 'N'),
1204
1217
elseif p == Inf
1205
1218
return inv (LAPACK. trcon! (' I' , $ uploc, $ isunitc, A. data))
1206
1219
else # use fallback
1207
- return cond (copyto ! (similar (parent (A)), A), p)
1220
+ return cond (copy ! (similar (parent (A)), A), p)
1208
1221
end
1209
1222
end
1210
1223
end
1211
1224
end
1212
1225
1213
1226
# multiplication
1214
1227
generic_trimatmul! (c:: StridedVector{T} , uploc, isunitc, tfun:: Function , A:: StridedMatrix{T} , b:: AbstractVector{T} ) where {T<: BlasFloat } =
1215
- BLAS. trmv! (uploc, tfun === identity ? ' N' : tfun === transpose ? ' T' : ' C' , isunitc, A, c === b ? c : copyto ! (c, b))
1228
+ BLAS. trmv! (uploc, tfun === identity ? ' N' : tfun === transpose ? ' T' : ' C' , isunitc, A, c === b ? c : copy ! (c, b))
1216
1229
function generic_trimatmul! (C:: StridedMatrix{T} , uploc, isunitc, tfun:: Function , A:: StridedMatrix{T} , B:: AbstractMatrix{T} ) where {T<: BlasFloat }
1217
1230
if stride (C,1 ) == stride (A,1 ) == 1
1218
- BLAS. trmm! (' L' , uploc, tfun === identity ? ' N' : tfun === transpose ? ' T' : ' C' , isunitc, one (T), A, C === B ? C : copyto ! (C, B))
1231
+ BLAS. trmm! (' L' , uploc, tfun === identity ? ' N' : tfun === transpose ? ' T' : ' C' , isunitc, one (T), A, C === B ? C : copy ! (C, B))
1219
1232
else # incompatible with BLAS
1220
1233
@invoke generic_trimatmul! (C:: AbstractMatrix , uploc, isunitc, tfun:: Function , A:: AbstractMatrix , B:: AbstractMatrix )
1221
1234
end
1222
1235
end
1223
1236
function generic_mattrimul! (C:: StridedMatrix{T} , uploc, isunitc, tfun:: Function , A:: AbstractMatrix{T} , B:: StridedMatrix{T} ) where {T<: BlasFloat }
1224
1237
if stride (C,1 ) == stride (B,1 ) == 1
1225
- BLAS. trmm! (' R' , uploc, tfun === identity ? ' N' : tfun === transpose ? ' T' : ' C' , isunitc, one (T), B, C === A ? C : copyto ! (C, A))
1238
+ BLAS. trmm! (' R' , uploc, tfun === identity ? ' N' : tfun === transpose ? ' T' : ' C' , isunitc, one (T), B, C === A ? C : copy ! (C, A))
1226
1239
else # incompatible with BLAS
1227
1240
@invoke generic_mattrimul! (C:: AbstractMatrix , uploc, isunitc, tfun:: Function , A:: AbstractMatrix , B:: AbstractMatrix )
1228
1241
end
1229
1242
end
1230
1243
# division
1231
1244
function generic_trimatdiv! (C:: StridedVecOrMat{T} , uploc, isunitc, tfun:: Function , A:: StridedMatrix{T} , B:: AbstractVecOrMat{T} ) where {T<: BlasFloat }
1232
1245
if stride (C,1 ) == stride (A,1 ) == 1
1233
- LAPACK. trtrs! (uploc, tfun === identity ? ' N' : tfun === transpose ? ' T' : ' C' , isunitc, A, C === B ? C : copyto ! (C, B))
1246
+ LAPACK. trtrs! (uploc, tfun === identity ? ' N' : tfun === transpose ? ' T' : ' C' , isunitc, A, C === B ? C : _copy_or_copyto ! (C, B))
1234
1247
else # incompatible with LAPACK
1235
1248
@invoke generic_trimatdiv! (C:: AbstractVecOrMat , uploc, isunitc, tfun:: Function , A:: AbstractMatrix , B:: AbstractVecOrMat )
1236
1249
end
1237
1250
end
1238
1251
function generic_mattridiv! (C:: StridedMatrix{T} , uploc, isunitc, tfun:: Function , A:: AbstractMatrix{T} , B:: StridedMatrix{T} ) where {T<: BlasFloat }
1239
1252
if stride (C,1 ) == stride (B,1 ) == 1
1240
- BLAS. trsm! (' R' , uploc, tfun === identity ? ' N' : tfun === transpose ? ' T' : ' C' , isunitc, one (T), B, C === A ? C : copyto ! (C, A))
1253
+ BLAS. trsm! (' R' , uploc, tfun === identity ? ' N' : tfun === transpose ? ' T' : ' C' , isunitc, one (T), B, C === A ? C : copy ! (C, A))
1241
1254
else # incompatible with BLAS
1242
1255
@invoke generic_mattridiv! (C:: AbstractMatrix , uploc, isunitc, tfun:: Function , A:: AbstractMatrix , B:: AbstractMatrix )
1243
1256
end
@@ -1962,22 +1975,22 @@ function powm!(A0::UpperTriangular, p::Real)
1962
1975
for i in axes (S,1 )
1963
1976
@inbounds S[i, i] = S[i, i] + 1
1964
1977
end
1965
- copyto ! (Stmp, S)
1978
+ copy ! (Stmp, S)
1966
1979
mul! (S, A, c)
1967
1980
ldiv! (Stmp, S)
1968
1981
1969
1982
c = (p - j) / (j4 - 2 )
1970
1983
for i in axes (S,1 )
1971
1984
@inbounds S[i, i] = S[i, i] + 1
1972
1985
end
1973
- copyto ! (Stmp, S)
1986
+ copy ! (Stmp, S)
1974
1987
mul! (S, A, c)
1975
1988
ldiv! (Stmp, S)
1976
1989
end
1977
1990
for i in axes (S,1 )
1978
1991
S[i, i] = S[i, i] + 1
1979
1992
end
1980
- copyto ! (Stmp, S)
1993
+ copy ! (Stmp, S)
1981
1994
mul! (S, A, - p)
1982
1995
ldiv! (Stmp, S)
1983
1996
for i in axes (S,1 )
@@ -1987,7 +2000,7 @@ function powm!(A0::UpperTriangular, p::Real)
1987
2000
blockpower! (A0, S, p/ (2 ^ s))
1988
2001
for m = 1 : s
1989
2002
mul! (Stmp. data, S, S)
1990
- copyto ! (S, Stmp)
2003
+ copy ! (S, Stmp)
1991
2004
blockpower! (A0, S, p/ (2 ^ (s- m)))
1992
2005
end
1993
2006
rmul! (S, normA0^ p)
@@ -2174,7 +2187,7 @@ function _find_params_log_quasitriu!(A)
2174
2187
break
2175
2188
end
2176
2189
_sqrt_quasitriu! (A isa UpperTriangular ? parent (A) : A, A)
2177
- copyto ! (AmI, A)
2190
+ copy ! (AmI, A)
2178
2191
for i in axes (AmI,1 )
2179
2192
@inbounds AmI[i,i] -= 1
2180
2193
end
0 commit comments