@@ -1291,6 +1291,27 @@ function A_rdiv_Bt!(A::StridedMatrix, B::UnitLowerTriangular)
1291
1291
A
1292
1292
end
1293
1293
1294
+ for f in (:A_rdiv_B! , :A_rdiv_Bc! , :A_rdiv_Bt! )
1295
+ for (uplo, fuplo) in ((:Lower , :tril! ), (:Upper , :triu! ))
1296
+ mat = Symbol (uplo, :Triangular )
1297
+ umat = Symbol (:Unit , mat)
1298
+ @eval begin
1299
+ $ f (A:: $mat , B:: Union{$mat,$umat} ) = ($ mat)($ f ($ fuplo (A. data), B))
1300
+ end
1301
+ end
1302
+ @eval $ f (A:: AbstractTriangular , B:: AbstractTriangular ) = $ f (full! (A), B)
1303
+ end
1304
+ for f in (:A_mul_B! , :Ac_mul_B! , :At_mul_B! , :A_ldiv_B! , :Ac_ldiv_B! , :At_ldiv_B! )
1305
+ for (uplo, fuplo) in ((:Lower , :tril! ), (:Upper , :triu! ))
1306
+ mat = Symbol (uplo, :Triangular )
1307
+ umat = Symbol (:Unit , mat)
1308
+ @eval begin
1309
+ $ f (A:: Union{$mat,$umat} , B:: $mat ) = ($ mat)($ f (A, $ fuplo (B. data)))
1310
+ end
1311
+ end
1312
+ @eval $ f (A:: AbstractTriangular , B:: AbstractTriangular ) = $ f (A, full! (B))
1313
+ end
1314
+
1294
1315
# Promotion
1295
1316
# # Promotion methods in matmul don't apply to triangular multiplication since it is inplace. Hence we have to make very similar definitions, but without allocation of a result array. For multiplication and unit diagonal division the element type doesn't have to be stable under division whereas that is necessary in the general triangular solve problem.
1296
1317
@@ -1301,72 +1322,91 @@ for t in (UpperTriangular, UnitUpperTriangular, LowerTriangular, UnitLowerTriang
1301
1322
end
1302
1323
end
1303
1324
1304
- for f in (:* , :Ac_mul_B , :At_mul_B , :\ , :Ac_ldiv_B , :At_ldiv_B )
1305
- @eval begin
1306
- ($ f)(A:: AbstractTriangular , B:: AbstractTriangular ) = ($ f)(A, full (B))
1325
+ for f in (:A_mul_Bc , :A_mul_Bt )
1326
+ for (uplo, fuplo) in ((:Lower , :tril! ), (:Upper , :triu! ))
1327
+ mat = Symbol (uplo, :Triangular )
1328
+ umat = Symbol (:Unit , mat)
1329
+ @eval begin
1330
+ function $f (A:: $mat , B:: Union{$mat,$umat} )
1331
+ TAB = typeof (zero (eltype (A))* zero (eltype (B)) + zero (eltype (A))* zero (eltype (B)))
1332
+ return ($ mat)($ f (copy_oftype (A, TAB), convert (AbstractMatrix{TAB}, B)))
1333
+ end
1334
+ end
1307
1335
end
1336
+ @eval $ f (A:: AbstractTriangular , B:: AbstractTriangular ) = $ f (full (A), B)
1308
1337
end
1309
- for f in (:A_mul_Bc , :A_mul_Bt , :Ac_mul_Bc , :At_mul_Bt , :/ , :A_rdiv_Bc , :A_rdiv_Bt )
1310
- @eval begin
1311
- ($ f)(A:: AbstractTriangular , B:: AbstractTriangular ) = ($ f)(full (A), B)
1338
+ for f in (:* , :Ac_mul_B , :At_mul_B )
1339
+ for (uplo, fuplo) in ((:Lower , :tril! ), (:Upper , :triu! ))
1340
+ mat = Symbol (uplo, :Triangular )
1341
+ umat = Symbol (:Unit , mat)
1342
+ @eval begin
1343
+ function $f (A:: Union{$mat,$umat} , B:: $mat )
1344
+ TAB = typeof (zero (eltype (A))* zero (eltype (B)) + zero (eltype (A))* zero (eltype (B)))
1345
+ return ($ mat)($ f (convert (AbstractMatrix{TAB}, A), copy_oftype (B, TAB)))
1346
+ end
1347
+ end
1312
1348
end
1349
+ @eval $ f (A:: AbstractTriangular , B:: AbstractTriangular ) = $ f (A, full (B))
1313
1350
end
1314
1351
1315
1352
# # The general promotion methods
1353
+ for mat in (:AbstractVector , AbstractMatrix)
1316
1354
# ## Multiplication with triangle to the left and hence rhs cannot be transposed.
1317
1355
for (f, g) in ((:* , :A_mul_B! ), (:Ac_mul_B , :Ac_mul_B! ), (:At_mul_B , :At_mul_B! ))
1318
1356
@eval begin
1319
- function ($ f){TA,TB} (A:: AbstractTriangular{TA} , B:: StridedVecOrMat{TB} )
1320
- TAB = typeof (zero (TA) * zero (TB) + zero (TA) * zero (TB ))
1357
+ function ($ f)(A:: AbstractTriangular , B:: $mat )
1358
+ TAB = typeof (zero (eltype (A)) * zero (eltype (B)) + zero (eltype (A)) * zero (eltype (B) ))
1321
1359
($ g)(convert (AbstractArray{TAB}, A), copy_oftype (B, TAB))
1322
1360
end
1323
1361
end
1324
1362
end
1325
1363
# ## Left division with triangle to the left hence rhs cannot be transposed. No quotients.
1326
1364
for (f, g) in ((:\ , :A_ldiv_B! ), (:Ac_ldiv_B , :Ac_ldiv_B! ), (:At_ldiv_B , :At_ldiv_B! ))
1327
1365
@eval begin
1328
- function ($ f){TA,TB,S} (A:: Union{UnitUpperTriangular{TA,S}, UnitLowerTriangular{TA,S}} , B:: StridedVecOrMat{TB} )
1329
- TAB = typeof (zero (TA) * zero (TB) + zero (TA) * zero (TB ))
1366
+ function ($ f)(A:: Union{UnitUpperTriangular, UnitLowerTriangular} , B:: $mat )
1367
+ TAB = typeof (zero (eltype (A)) * zero (eltype (B)) + zero (eltype (A)) * zero (eltype (B) ))
1330
1368
($ g)(convert (AbstractArray{TAB}, A), copy_oftype (B, TAB))
1331
1369
end
1332
1370
end
1333
1371
end
1334
1372
# ## Left division with triangle to the left hence rhs cannot be transposed. Quotients.
1335
1373
for (f, g) in ((:\ , :A_ldiv_B! ), (:Ac_ldiv_B , :Ac_ldiv_B! ), (:At_ldiv_B , :At_ldiv_B! ))
1336
1374
@eval begin
1337
- function ($ f){TA,TB,S} (A:: Union{UpperTriangular{TA,S}, LowerTriangular{TA,S}} , B:: StridedVecOrMat{TB} )
1338
- TAB = typeof ((zero (TA) * zero (TB) + zero (TA) * zero (TB)) / one (TA ))
1375
+ function ($ f)(A:: Union{UpperTriangular, LowerTriangular} , B:: $mat )
1376
+ TAB = typeof ((zero (eltype (A)) * zero (eltype (B)) + zero (eltype (A)) * zero (eltype (B))) / one (eltype (A) ))
1339
1377
($ g)(convert (AbstractArray{TAB}, A), copy_oftype (B, TAB))
1340
1378
end
1341
1379
end
1342
1380
end
1343
1381
# ## Multiplication with triangle to the rigth and hence lhs cannot be transposed.
1344
1382
for (f, g) in ((:* , :A_mul_B! ), (:A_mul_Bc , :A_mul_Bc! ), (:A_mul_Bt , :A_mul_Bt! ))
1345
1383
@eval begin
1346
- function ($ f){TA,TB} (A:: StridedVecOrMat{TA} , B:: AbstractTriangular{TB} )
1347
- TAB = typeof (zero (TA) * zero (TB) + zero (TA) * zero (TB ))
1384
+ function ($ f)(A:: $mat , B:: AbstractTriangular )
1385
+ TAB = typeof (zero (eltype (A)) * zero (eltype (B)) + zero (eltype (A)) * zero (eltype (B) ))
1348
1386
($ g)(copy_oftype (A, TAB), convert (AbstractArray{TAB}, B))
1349
1387
end
1350
1388
end
1351
1389
end
1352
1390
# ## Right division with triangle to the right hence lhs cannot be transposed. No quotients.
1353
1391
for (f, g) in ((:/ , :A_rdiv_B! ), (:A_rdiv_Bc , :A_rdiv_Bc! ), (:A_rdiv_Bt , :A_rdiv_Bt! ))
1354
1392
@eval begin
1355
- function ($ f){TA,TB,S} (A:: StridedVecOrMat{TA} , B:: Union{UnitUpperTriangular{TB,S}, UnitLowerTriangular{TB,S} } )
1356
- TAB = typeof (zero (TA) * zero (TB) + zero (TA) * zero (TB ))
1393
+ function ($ f)(A:: $mat , B:: Union{UnitUpperTriangular, UnitLowerTriangular} )
1394
+ TAB = typeof (zero (eltype (A)) * zero (eltype (B)) + zero (eltype (A)) * zero (eltype (B) ))
1357
1395
($ g)(copy_oftype (A, TAB), convert (AbstractArray{TAB}, B))
1358
1396
end
1359
1397
end
1360
1398
end
1399
+
1361
1400
# ## Right division with triangle to the right hence lhs cannot be transposed. Quotients.
1362
1401
for (f, g) in ((:/ , :A_rdiv_B! ), (:A_rdiv_Bc , :A_rdiv_Bc! ), (:A_rdiv_Bt , :A_rdiv_Bt! ))
1363
1402
@eval begin
1364
- function ($ f){TA,TB,S} (A:: StridedVecOrMat{TA} , B:: Union{UpperTriangular{TB,S}, LowerTriangular{TB,S} } )
1365
- TAB = typeof ((zero (TA) * zero (TB) + zero (TA) * zero (TB)) / one (TA ))
1403
+ function ($ f)(A:: $mat , B:: Union{UpperTriangular, LowerTriangular} )
1404
+ TAB = typeof ((zero (eltype (A)) * zero (eltype (B)) + zero (eltype (A)) * zero (eltype (B))) / one (eltype (A) ))
1366
1405
($ g)(copy_oftype (A, TAB), convert (AbstractArray{TAB}, B))
1367
1406
end
1368
1407
end
1369
1408
end
1409
+ end
1370
1410
# ## Fallbacks brought in from linalg/bidiag.jl while fixing #14506.
1371
1411
# Eventually the above promotion methods should be generalized as
1372
1412
# was done for bidiagonal matrices in #14506.
0 commit comments