|
545 | 545 | rmul!(A::Union{UpperTriangular,LowerTriangular}, c::Number) = mul!(A, A, c)
|
546 | 546 | lmul!(c::Number, A::Union{UpperTriangular,LowerTriangular}) = mul!(A, c, A)
|
547 | 547 |
|
| 548 | +function dot(x::AbstractVector, A::UpperTriangular, y::AbstractVector) |
| 549 | + require_one_based_indexing(x, y) |
| 550 | + m = size(A, 1) |
| 551 | + (length(x) == m == length(y)) || throw(DimensionMismatch()) |
| 552 | + if iszero(m) |
| 553 | + return dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))) |
| 554 | + end |
| 555 | + x₁ = x[1] |
| 556 | + r = dot(x₁, A[1,1], y[1]) |
| 557 | + @inbounds for j in 2:m |
| 558 | + yj = y[j] |
| 559 | + if !iszero(yj) |
| 560 | + temp = adjoint(A[1,j]) * x₁ |
| 561 | + @simd for i in 2:j |
| 562 | + temp += adjoint(A[i,j]) * x[i] |
| 563 | + end |
| 564 | + r += dot(temp, yj) |
| 565 | + end |
| 566 | + end |
| 567 | + return r |
| 568 | +end |
| 569 | +function dot(x::AbstractVector, A::UnitUpperTriangular, y::AbstractVector) |
| 570 | + require_one_based_indexing(x, y) |
| 571 | + m = size(A, 1) |
| 572 | + (length(x) == m == length(y)) || throw(DimensionMismatch()) |
| 573 | + if iszero(m) |
| 574 | + return dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))) |
| 575 | + end |
| 576 | + x₁ = first(x) |
| 577 | + r = dot(x₁, y[1]) |
| 578 | + @inbounds for j in 2:m |
| 579 | + yj = y[j] |
| 580 | + if !iszero(yj) |
| 581 | + temp = adjoint(A[1,j]) * x₁ |
| 582 | + @simd for i in 2:j-1 |
| 583 | + temp += adjoint(A[i,j]) * x[i] |
| 584 | + end |
| 585 | + r += dot(temp, yj) |
| 586 | + r += dot(x[j], yj) |
| 587 | + end |
| 588 | + end |
| 589 | + return r |
| 590 | +end |
| 591 | +function dot(x::AbstractVector, A::LowerTriangular, y::AbstractVector) |
| 592 | + require_one_based_indexing(x, y) |
| 593 | + m = size(A, 1) |
| 594 | + (length(x) == m == length(y)) || throw(DimensionMismatch()) |
| 595 | + if iszero(m) |
| 596 | + return dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))) |
| 597 | + end |
| 598 | + r = zero(typeof(dot(first(x), first(A), first(y)))) |
| 599 | + @inbounds for j in 1:m |
| 600 | + yj = y[j] |
| 601 | + if !iszero(yj) |
| 602 | + temp = adjoint(A[j,j]) * x[j] |
| 603 | + @simd for i in j+1:m |
| 604 | + temp += adjoint(A[i,j]) * x[i] |
| 605 | + end |
| 606 | + r += dot(temp, yj) |
| 607 | + end |
| 608 | + end |
| 609 | + return r |
| 610 | +end |
| 611 | +function dot(x::AbstractVector, A::UnitLowerTriangular, y::AbstractVector) |
| 612 | + require_one_based_indexing(x, y) |
| 613 | + m = size(A, 1) |
| 614 | + (length(x) == m == length(y)) || throw(DimensionMismatch()) |
| 615 | + if iszero(m) |
| 616 | + return dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))) |
| 617 | + end |
| 618 | + r = zero(typeof(dot(first(x), first(y)))) |
| 619 | + @inbounds for j in 1:m |
| 620 | + yj = y[j] |
| 621 | + if !iszero(yj) |
| 622 | + temp = x[j] |
| 623 | + @simd for i in j+1:m |
| 624 | + temp += adjoint(A[i,j]) * x[i] |
| 625 | + end |
| 626 | + r += dot(temp, yj) |
| 627 | + end |
| 628 | + end |
| 629 | + return r |
| 630 | +end |
| 631 | + |
548 | 632 | fillstored!(A::LowerTriangular, x) = (fillband!(A.data, x, 1-size(A,1), 0); A)
|
549 | 633 | fillstored!(A::UnitLowerTriangular, x) = (fillband!(A.data, x, 1-size(A,1), -1); A)
|
550 | 634 | fillstored!(A::UpperTriangular, x) = (fillband!(A.data, x, 0, size(A,2)-1); A)
|
|
0 commit comments