Skip to content

Unnecessary add operations performed when multiplying in-place by diagonal matrix #963

@tristanmontoya

Description

@tristanmontoya

Left-multiplication of a vector of length N by an N-by-N diagonal matrix should require a total of N multiplications. However, there are certain cases when (at least according to GFlops.jl) Julia appears to perform an additional N additions, effectively doubling the cost of such an operation. For example, the following code, which uses an out-of-place matrix-vector multiplication,

using LinearAlgebra, GFlops
A = Diagonal(rand(10))
x = rand(10)
@count_ops y = A * x

produces the following output:

Flop Counter: 10 flop
┌─────┬─────────┐
│     │ Float64 │
├─────┼─────────┤
│ mul │      10 │
└─────┴─────────┘

However, the equivalent in-place operation,

y = similar(x)
@count_ops mul!(y, A, x)

returns the following:

Flop Counter: 20 flop
┌─────┬─────────┐
│     │ Float64 │
├─────┼─────────┤
│ add │      10 │
│ mul │      10 │
└─────┴─────────┘

It seems like these additions are not necessary; the same operation could be done without any addition as follows:

function LinearAlgebra.mul!(y::AbstractVector, 
    A::Diagonal, x::AbstractVector)
    y[:] = A.diag .* x
    return y
end

Is this an oversight or is there a reason for such behaviour?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions