# Why is \`UniformScaling\` not a subtype of \`AbstractArray\`?

**URL:** <https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412>\
**Category:** General Usage\
**Created:** [April 27, 2017, 11:39pm UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412 "2017-04-27T23:39:15Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pbellive](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbellive/32/3604_2.png) [@Pbellive](https://discourse.julialang.org/u/Pbellive)\
**Post date:** [April 27, 2017, 11:39pm UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/1 "2017-04-27T23:39:15Z")

</div>

Say I have the following line of code in Julia

```julia
C = A*B

```

where `A` and `B` are matrices, i.e.

```julia
typeof(A) == typeof(B) <: AbstractMatrix

```

If `A` is a multiple of the appropriately sized identity matrix then it is convenient to represent it as `A = UniformScaling(x)` for some scalar `x`. That works great except when you need to create `A` in one function then pass it into another. `UniformScaling` is not a subtype of `AbstractArray` (this is the case in Julia 0.5 and on master) so the following code doesn’t work

```julia
f(A::AbstractMatrix,B::AbstractMatrix) = A*B

A = UniformScaling(1.0);
B = sprandn(100,100,0.1);
C = f(A,B)

```

which you can quickly confirm at the REPL:

```julia
julia> f(A::AbstractMatrix,B::AbstractMatrix) = A*B
f (generic function with 1 method)

julia> A = UniformScaling(1.0);

julia> B = sprandn(100,100,0.1);

julia> C = f(A,B)
ERROR: MethodError: no method matching f(::UniformScaling{Float64}, ::SparseMatrixCSC{Float64,Int64})
Closest candidates are:
  f(::AbstractArray{T,2}, ::AbstractArray{T,2}) at REPL[1]:1

julia> 

```

I’m wondering if that is the intended behaviour or a bug? The one reason I can think of off the top of my head for why UniformScaling shouldn’t be a subtype of AbstractArray is that methods that should be supported for any array type (e.g. size, ndims) don’t exist for UniformScaling. I don’t know enough to know if that’s reason to nix the idea or not.

If the consensus is that making `UniformScaling` a subtype of `AbstractArray` is a good idea, I’ll make a PR. If not, does anyone know of another way to generate a placeholder for a very large identity matrix with a negligible memory footprint that can be passed to functions that take `AbstractMatrix` inputs?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [April 27, 2017, 11:45pm UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/2 "2017-04-27T23:45:12Z")

</div>

> [@Pbellive](#):
>
> The one reason I can think of off the top of my head for why UniformScaling shouldn’t be a subtype of AbstractArray is that methods that should be supported for any array type (e.g. size, ndims) don’t exist for UniformScaling.

I think this is the case: it doesn’t support the full `Array` interface. But I would like to see a `UniformScaling` with size that does satisfy the full interface.

BTW, this is usually fixed by just not strictly typing the functions so much.

---

<div class="post-metadata">

**Author:** ![Pbellive](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbellive/32/3604_2.png) [@Pbellive](https://discourse.julialang.org/u/Pbellive)\
**Post date:** [April 28, 2017, 12:15am UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/3 "2017-04-28T00:15:06Z")

</div>

Thanks for the reply Chris. Requiring something to support the full array interface in order to be an array is fair enough. I agree that adding something akin to `UniformScaling` with a size would be nice. I’ll have to think a bit more about that but in the meantime I guess I’ll just have to loosen my function signature typing.

---

<div class="post-metadata">

**Author:** ![tobydriscoll](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tobydriscoll/32/1843_2.png) [@tobydriscoll](https://discourse.julialang.org/u/tobydriscoll)\
**Post date:** [March 30, 2018, 3:41pm UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/4 "2018-03-30T15:41:52Z")

</div>

Was an issue or PR ever created? Almost a year later, I ran into essentially the same problem for a built-in matrix function:

```julia
julia> kron(rand(3,2),UniformScaling(3))
ERROR: MethodError: no method matching kron(::Array{Float64,2}, ::UniformScaling{Int64})
Closest candidates are:
  kron(::Any, ::Any, ::Any, ::Any...) at operators.jl:466
  kron(::Union{Array{T,1}, Array{T,2}} where T, ::SparseArrays.SparseMatrixCSC) at /Users/vagrant/worker/worker/package_osx64/build/usr/share/julia/site/v0.7/SparseArrays/src/linalg.jl:823
  kron(::AbstractArray{T,2}, ::AbstractArray{S,2}) where {T, S} at /Users/vagrant/worker/worker/package_osx64/build/usr/share/julia/site/v0.7/LinearAlgebra/src/dense.jl:379
  ...

julia> versioninfo()
Julia Version 0.7.0-DEV.4698
Commit a9eaa4f (2018-03-26 18:49 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin14.5.0)
  CPU: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, haswell)
Environment:

```

I’m also puzzled why the deprecation warning for `eye` tells me to use `Matrix(1.0I,3,3)` rather than the sparser and more precise `Diagonal(ones(3))`. Is there a downside to the latter, or was this a case of “just give them an array”? (Of course, I suspect that `ones` probably isn’t long for this world, either.)

I know there have been a lot of electrons spilled on the problems with convenience functions such as `eye`, and on the meaning of `UniformScaling`. From outside the debate, it doesn’t feel fully sorted out yet. As a long-time Matlab fanboy, I hope the Julia powers that be don’t lose sight of the incredible value Matlab created (and numpy piggybacked on) through unity and simplicity for interactive computing.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [March 30, 2018, 3:50pm UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/5 "2018-03-30T15:50:56Z")

</div>

> [@tobydriscoll](#):
>
> I’m also puzzled why the deprecation warning for eye tells me to use Matrix(1.0I,3,3) rather than the sparser and more precise Diagonal(ones(3)). Is there a downside to the latter, or was this a case of “just give them an array”? (Of course, I suspect that ones probably isn’t long for this world, either.)

`eye` returned a dense array and not a `Diagonal`, so it’s not the same (but is better).

---

<div class="post-metadata">

**Author:** ![Pbellive](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbellive/32/3604_2.png) [@Pbellive](https://discourse.julialang.org/u/Pbellive)\
**Post date:** [March 31, 2018, 3:21am UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/6 "2018-03-31T03:21:05Z")

</div>

As far as I know (and can tell by searching the main Julia repo) there haven’t been any PRs or issues directly asking for `UniformScaling` to become a subtype of `AbstractArray`. From [this issue](https://github.com/JuliaLang/julia/issues/23197)  
It seems that at least Andreas Noack would prefer that they not be sized, which would be a prerequisite to `AbstractArray` status.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [March 31, 2018, 4:21am UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/7 "2018-03-31T04:21:10Z")

</div>

What if something like the following is defined:

```julia
(J::UniformScaling{T})(d::Int) where {T} = Diagonal(fill(J.λ, d))

```

Then you could construct dimensioned matrices …

```julia
Julia-0.6.2> I(3)
3×3 Diagonal{Int64}:
 1 ⋅ ⋅
 ⋅ 1 ⋅
 ⋅ ⋅ 1

Julia-0.6.2> 1.0I(3)
3×3 Diagonal{Float64}:
 1.0 ⋅ ⋅
  ⋅ 1.0 ⋅
  ⋅ ⋅ 1.0

```

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [March 31, 2018, 4:41am UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/8 "2018-03-31T04:41:58Z")

</div>

Hmm, that might be a great idea! Could combine this with something like the [`Eye` type from FillArrays.jl](https://github.com/JuliaArrays/FillArrays.jl/blob/028c1ff46c3e07576f0caa5daa0780f731522c00/src/FillArrays.jl#L92) to get zero allocations.

Edit: or rather

```julia
struct ScalarMatrix{T} <: AbstractMatrix{T}
    val::T
    n::Int
end
Base.size(A::ScalarMatrix) = (A.n, A.n)
Base.getindex(A::ScalarMatrix, i::Int, j::Int) = ifelse(i == j, A.val, zero(A.val))
Base.:*(x::Number, A::ScalarMatrix) = ScalarMatrix(x * A.val, A.n)
Base.:*(A::ScalarMatrix, x::Number) = x * A

(J::UniformScaling{T})(d::Int) where {T} = ScalarMatrix(J.λ, d)

```

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [March 31, 2018, 3:58pm UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/9 "2018-03-31T15:58:55Z")

</div>

I guess this was proposed in [https://github.com/JuliaLang/julia/issues/23156](https://github.com/JuliaLang/julia/issues/23156). Unfortunately the proposal was not implemented, despite some initial support.

---

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [March 1, 2023, 10:57am UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/10 "2023-03-01T10:57:53Z")

</div>

I just ran into this again. What was the reason that UniformScaling is not a type of AbstractArray?

---

<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:** [March 1, 2023, 2:14pm UTC](https://discourse.julialang.org/t/why-is-uniformscaling-not-a-subtype-of-abstractarray/3412/11 "2023-03-01T14:14:24Z")

</div>

It doesn’t have a size until you use it. The AbstractArray interface requires `size` to be defined.
