# Special case \`lmul!(0, ::AbstractArray)\`?

**URL:** https://discourse.julialang.org/t/special-case-lmul-0-abstractarray/93557
**Category:** Internals & Design
**Tags:** array, linearalgebra
**Created:** [January 26, 2023, 7:07am UTC](https://discourse.julialang.org/t/special-case-lmul-0-abstractarray/93557 "2023-01-26T07:07:26Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)
#### Post date: [January 26, 2023, 7:07am UTC](https://discourse.julialang.org/t/special-case-lmul-0-abstractarray/93557/1 "2023-01-26T07:07:26Z")

</div>

```julia
julia> using LinearAlgebra

julia> function lmul2!(s::Number, X::AbstractArray)
           iszero(s) && return fill!(X, s)
           @simd for I in eachindex(X)
               @inbounds X[I] = s*X[I]
           end
           X
       end
lmul2! (generic function with 1 method)

julia> A = rand(1000, 1000);

julia> @btime (A -> lmul!(0, A))($A);
  290.313 μs (0 allocations: 0 bytes)

julia> @btime (A -> lmul2!(0, A))($A);
  222.413 μs (0 allocations: 0 bytes)

```

Perhaps the compiler should transform the loop to a `fill!`. It does seem to handle `1` specially, transforming the loop to a no-op.

```julia
julia> @btime (A -> lmul!(1, A))($A);
  2.883 ns (0 allocations: 0 bytes)

```

If this is complicated, adding an `iszero` check may help with performance.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [January 26, 2023, 2:25pm UTC](https://discourse.julialang.org/t/special-case-lmul-0-abstractarray/93557/2 "2023-01-26T14:25:47Z")

</div>

The compiler is doing the best it can in the face of `NaN`s and `Inf`s, I think. `1*[2.3 NaN Inf]` is indeed `[2.3 NaN Inf]`, but `0*[2.3 NaN Inf]` isn’t `[0.0 0.0 0.0]`.

---

<div class="post-metadata">

### Author: ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)
#### Post date: [January 26, 2023, 4:41pm UTC](https://discourse.julialang.org/t/special-case-lmul-0-abstractarray/93557/3 "2023-01-26T16:41:37Z")

</div>

One can debate the merits, but there is precedent for strong zeros in linear algebra functions:

```julia-repl
using LinearAlgebra

julia> A = fill(1.0,3,3); B = fill(NaN,3,3); C = fill(NaN,3,3);

julia> mul!(C,A,B,0.0,0.0)
3×3 Matrix{Float64}:
 0.0 0.0 0.0
 0.0 0.0 0.0
 0.0 0.0 0.0

```

Even if we don’t like numeric zeros acting as strong zeros, we could certainly adopt `false` since it already acts that way.

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [January 26, 2023, 5:00pm UTC](https://discourse.julialang.org/t/special-case-lmul-0-abstractarray/93557/4 "2023-01-26T17:00:35Z")

</div>

> [@jishnub](#):
>
> `iszero(s) && return fill!(X, s)`

Regardless of other discussion,

```julia
iszero(s) && return fill!(X, s*one(eltype(X)))

```

might be appropriate (on the fence, the original looks much cleaner)
