# How to convert UniformScaling with single entry to Number?

**URL:** https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751
**Category:** General Usage
**Tags:** question, numbers, array, linearalgebra
**Created:** [October 21, 2020, 2:51pm UTC](https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751 "2020-10-21T14:51:33Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [October 21, 2020, 2:51pm UTC](https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751/1 "2020-10-21T14:51:33Z")

</div>

**Copying a question from Zulip given that it may be useful in general to discuss in Discourse…**

A good trick to perform algebraic operations with both arrays and numbers generically is to use `LinearAlgebra.I` instead of `1`:

```julia
julia> f(x) = x*I
f (generic function with 1 method)

julia> f(1)
UniformScaling{Int64}
1*I

julia> f(ones(3,3))
3×3 Array{Float64,2}:
 1.0 1.0 1.0
 1.0 1.0 1.0
 1.0 1.0 1.0

```

The problem I have is that the function `f` is used a lot with simple numbers, and the return type of `f(1)` is not a `Number`. How do we get around this issue? Is there a function in Base that converts a `UniformScaling` with a single entry to a simple `Number`?

If I can provide a simple number in most cases, I will have less issues downstream, and the compiler will likely perform more low-level optimizations?

I know that a `UniformScaling` object `a` with a single entry has the field `a.λ` with the actual number it represents. I wonder how to retrieve this number elegantly, possibly without performance penalties.

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [October 21, 2020, 3:05pm UTC](https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751/2 "2020-10-21T15:05:40Z")

</div>

maybe you can use `one` depending how much laziness you need:

```julia
julia> one(3)
1

julia> one(rand(3,3))
3×3 Array{Float64,2}:
 1.0 0.0 0.0
 0.0 1.0 0.0
 0.0 0.0 1.0

```

or you can add a method to Number (or name it something else):

```julia
julia> Base.Number(a::UniformScaling) = a.λ

julia> Number(I*3)
3

julia> Number(I*3.0)
3.0

```

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [October 21, 2020, 3:14pm UTC](https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751/3 "2020-10-21T15:14:15Z")

</div>

How to create a method that works with arrays too? In other words how to dispatch on different kinds of UniformScaling and retrieve the underlying array vs. number?

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [October 21, 2020, 3:17pm UTC](https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751/4 "2020-10-21T15:17:25Z")

</div>

actually, if your `f` can return array, why does it need to be a `Number`? `UniformScaling` should act as an array in any cases.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [October 21, 2020, 4:33pm UTC](https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751/5 "2020-10-21T16:33:45Z")

</div>

Because most packages out there fall into this Julia anti-pattern where the code constrains the type of functions to numbers, e.g. `f(x::Number) = ...` prematurely. Also, I am assuming that the compiler can do more magic with the raw numbers in general compared to a more complicated struct.

The code I am referring to is in this PR: [https://github.com/JuliaEarth/Variography.jl/pull/33](https://github.com/JuliaEarth/Variography.jl/pull/33)

I would like to be able to do `g = GaussianVariogram() + SphericalVariogram()` and then evaluate the function with `g(1.0)` and get a number.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [October 21, 2020, 5:14pm UTC](https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751/6 "2020-10-21T17:14:57Z")

</div>

I followed your suggestion and added:

```julia
raw(a::UniformScaling) = a.λ
raw(a) = a

```

to extract the underlying number when we get a uniform scaling object.

Thanks for the help.

---

<div class="post-metadata">

### Author: ![raminammour](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raminammour/32/13572_2.png) [@raminammour](https://discourse.julialang.org/u/raminammour)
#### Post date: [October 21, 2020, 5:22pm UTC](https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751/7 "2020-10-21T17:22:17Z")

</div>

Haven’t thought about it for too long but:

```julia
julia> (f(x::T)::T) where T = x*I
f (generic function with 1 method)

#not sure if this interferes with something else...
julia> Base.convert(::Type{T}, u::UniformScaling{T}) where T<:Number = u.λ

julia> f(1)
1

julia> f(3.0)
3.0

julia> f(rand(2,2))
2×2 Array{Float64,2}:
 0.054866 0.471527
 0.938986 0.538114

julia> g(x)= x*I
g (generic function with 1 method)

julia> using BenchmarkTools

julia> @btime g($1)
  0.037 ns (0 allocations: 0 bytes)
UniformScaling{Int64}
1*I

julia> @btime f($1)
  0.036 ns (0 allocations: 0 bytes)
1

julia> @btime f($1.0)
  0.037 ns (0 allocations: 0 bytes)
1.0

julia> @btime g($1.0)
  0.035 ns (0 allocations: 0 bytes)
UniformScaling{Float64}
1.0*I

julia> @btime g($(rand(3,3)))
  43.347 ns (1 allocation: 160 bytes)
3×3 Array{Float64,2}:
 0.543145 0.0292201 0.670174
 0.754201 0.290328 0.459809
 0.896825 0.678289 0.332216

julia> @btime f($(rand(3,3)))
  43.347 ns (1 allocation: 160 bytes)
3×3 Array{Float64,2}:
 0.32656 0.582854 0.952984
 0.0462256 0.589197 0.0384532
 0.972349 0.160872 0.807338

```

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [October 21, 2020, 5:36pm UTC](https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751/8 "2020-10-21T17:36:57Z")

</div>

Nice trick with conversion methods 👍 I will follow the simple approach above with a `raw` function to avoid thinking about it too much.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [October 22, 2020, 11:56am UTC](https://discourse.julialang.org/t/how-to-convert-uniformscaling-with-single-entry-to-number/48751/9 "2020-10-22T11:56:20Z")

</div>

> [@juliohm](#):
>
> most packages out there fall into this Julia anti-pattern where the code constrains the type of functions to numbers, e.g. `f(x::Number) = ...` prematurely

I think that effort is best allocated to fixing these instead of introducing a workaround.

> [@juliohm](#):
>
> I am assuming that the compiler can do more magic with the raw numbers in general compared to a more complicated struct

That may not be true, especially if the `struct` just wraps a number.
