Is this a bug?

```
A = sparse(Int32[], Int32[], Float64[], 2, 2)
A + I # Loses Int32
```

`A`

is of type `SparseMatrixCSC{Float64,Int32}`

and `A + I`

is of type `SparseMatrixCSC{Float64,Int64}`

, losing the integer type.

Thanks

Is this a bug?

```
A = sparse(Int32[], Int32[], Float64[], 2, 2)
A + I # Loses Int32
```

`A`

is of type `SparseMatrixCSC{Float64,Int32}`

and `A + I`

is of type `SparseMatrixCSC{Float64,Int64}`

, losing the integer type.

Thanks

```
julia> @which A+I
+(A::SparseMatrixCSC, J::UniformScaling) in SparseArrays at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/SparseArrays/src/sparsematrix.jl:3500
```

This is the code:

```
(+)(A::SparseMatrixCSC, J::UniformScaling) = A + sparse(J, size(A)...)
```

Now

```
julia> typeof(size(A))
Tuple{Int64,Int64}
julia> @which size(A)
size(S::SparseMatrixCSC) in SparseArrays at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/SparseArrays/src/sparsematrix.jl:36
```

```
size(S::SparseMatrixCSC) = (S.m, S.n)
```

```
struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrix{Tv,Ti}
m::Int # Number of rows
n::Int # Number of columns
```

Maybe this should be:

```
struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrix{Tv,Ti}
m::Ti # Number of rows
n::Ti # Number of columns
```

I don’t think that’s enough because

```
sparse(I, Int32(3), Int32(3))
```

still has integer type `Int64`

. Maybe it can be solved changing the definition of `+`

, since

```
SparseMatrixCSC{Float64,Int32}(I, 3, 3)
```

works.

Should I open an issue? I think I can fix it.

I don’t see how it is related to +.

```
julia> @which sparse(I, Int32(3), Int32(3))
sparse(s::UniformScaling, m::Integer, n::Integer) in SparseArrays at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/SparseArrays/src/sparsematrix.jl:1558
```

This is the code:

```
sparse(s::UniformScaling, dims::Dims{2}) = SparseMatrixCSC(s, dims)
sparse(s::UniformScaling, m::Integer, n::Integer) = sparse(s, Dims((m, n)))
```

```
help?> Dims
search: Dims ndims DimensionMismatch permutedims permutedims! PermutedDimsArray dropdims selectdim diagm spdiagm divrem dirname RoundingMode ENDIAN_BOM
Dims{N}
An NTuple of N Ints used to represent the dimensions of an AbstractArray.
julia> Dims
Tuple{Vararg{Int64,N}} where N
```

Maybe replacing

```
sparse(s::UniformScaling, dims::Dims{2}) = SparseMatrixCSC(s, dims)
sparse(s::UniformScaling, m::Integer, n::Integer) = sparse(s, Dims((m, n)))
```

by:

```
sparse(s::UniformScaling, m::Integer, n::Integer) = SparseMatrixCSC(s, promote(m,n))
```

and replacing in all constructors (part of concerned code unmodified below) of SparseMatrixCSC Integer by template Ti<:Integer:

```
SparseMatrixCSC{Tv,Ti}(s::UniformScaling, m::Integer, n::Integer) where {Tv,Ti} = SparseMatrixCSC{Tv,Ti}(s, Dims((m, n)))
SparseMatrixCSC{Tv}(s::UniformScaling, m::Integer, n::Integer) where {Tv} = SparseMatrixCSC{Tv}(s, Dims((m, n)))
SparseMatrixCSC(s::UniformScaling, m::Integer, n::Integer) = SparseMatrixCSC(s, Dims((m, n)))
SparseMatrixCSC{Tv}(s::UniformScaling, dims::Dims{2}) where {Tv} = SparseMatrixCSC{Tv,Int}(s, dims)
SparseMatrixCSC(s::UniformScaling, dims::Dims{2}) = SparseMatrixCSC{eltype(s)}(s, dims)
function SparseMatrixCSC{Tv,Ti}(s::UniformScaling, dims::Dims{2}) where {Tv,Ti}
@boundscheck first(dims) < 0 && throw(ArgumentError("first dimension invalid ($(first(dims)) < 0)"))
@boundscheck last(dims) < 0 && throw(ArgumentError("second dimension invalid ($(last(dims)) < 0)"))
iszero(s.λ) && return spzeros(Tv, Ti, dims...)
m, n, k = dims..., min(dims...)
nzval = fill!(Vector{Tv}(undef, k), Tv(s.λ))
rowval = copyto!(Vector{Ti}(undef, k), 1:k)
colptr = copyto!(Vector{Ti}(undef, n + 1), 1:(k + 1))
for i in (k + 2):(n + 1) colptr[i] = (k + 1) end
SparseMatrixCSC{Tv,Ti}(dims..., colptr, rowval, nzval)
end
```

But the fact that Dims is defined as an Int64 tuple may have other implications…

I’m saying that instead of redefining `SparseMatrixCSC{Tv,Ti}`

so that its sizes have type `Ti`

, we simply change

```
(+)(A::SparseMatrixCSC, J::UniformScaling) = A + sparse(J, size(A)...)
```

to something like

```
(+)(A::SparseMatrixCSC{Tv,Ti}, J::UniformScaling) where {Tv, Ti <: Integer} =
A + SparseMatrixCSC{Tv,Ti}(J, size(A)...)
```

But this would only work for +. What about -?

The rest of the code should be made consistent. The first thing bothering me is that Dims is defined with Int64 but SparseMatrix is allowed to have custom indices type. It should be made consistent.

```
julia> Dims
Tuple{Vararg{Int64,N}} where N
```

Yes, - as well. And I + A also. All three are together in the code.

While it might solve your particular problem, it may not be a definitive solution. There are other methods that use Int64 (eg via Dims) and the number of rows and cols being stored as Int64 makes it unusable for BigInt indices (which are not practical for dense stored arrays but may be useful for sparse arrays or lazy evaluation arrays).