|
87 | 87 | @inline Base.zero(a::SA) where {SA <: StaticArray} = zeros(SA)
|
88 | 88 | @inline Base.zero(a::Type{SA}) where {SA <: StaticArray} = zeros(SA)
|
89 | 89 |
|
| 90 | +@inline _construct_sametype(a::Type, elements) = a(elements) |
| 91 | +@inline _construct_sametype(a, elements) = typeof(a)(elements) |
| 92 | + |
90 | 93 | @inline one(m::StaticMatrixLike) = _one(Size(m), m)
|
91 | 94 | @inline one(::Type{SM}) where {SM<:StaticMatrixLike}= _one(Size(SM), SM)
|
92 | 95 | function _one(s::Size, m_or_SM)
|
93 | 96 | if (length(s) != 2) || (s[1] != s[2])
|
94 | 97 | throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
|
95 | 98 | end
|
96 |
| - _scalar_matrix(s, m_or_SM, one(_eltype_or(m_or_SM, Float64))) |
| 99 | + λ = one(_eltype_or(m_or_SM, Float64)) |
| 100 | + _construct_sametype(m_or_SM, _scalar_matrix_elements(s, λ)) |
| 101 | + # TODO: Bring back the use of _construct_similar here: |
| 102 | + # _construct_similar(m_or_SM, s, _scalar_matrix_elements(s, λ)) |
| 103 | + # |
| 104 | + # However, because _construct_similar uses `similar_type`, it will be |
| 105 | + # breaking for some StaticMatrix types (in particular Rotations.RotMatrix) |
| 106 | + # which must have similar_type return a general type able to hold any |
| 107 | + # matrix in the full general linear group. |
| 108 | + # |
| 109 | + # (Generally we're stuck here and things like RotMatrix really need to |
| 110 | + # override one() and zero() themselves: on the one hand, one(RotMatrix) |
| 111 | + # should return a RotMatrix, but zero(RotMatrix) can not be a RotMatrix. |
| 112 | + # The best StaticArrays can do is to use similar_type to return an SMatrix |
| 113 | + # for both of these, and let the more specialized library define the |
| 114 | + # correct algebraic properties.) |
97 | 115 | end
|
98 | 116 |
|
99 | 117 | # StaticMatrix(I::UniformScaling)
|
100 |
| -(::Type{SM})(I::UniformScaling) where {SM<:StaticMatrix} = _scalar_matrix(Size(SM), SM, I.λ) |
| 118 | +(::Type{SM})(I::UniformScaling) where {SM<:StaticMatrix} = |
| 119 | + SM(_scalar_matrix_elements(Size(SM), I.λ)) |
101 | 120 | # The following oddity is needed if we want `SArray{Tuple{2,3}}(I)` to work
|
102 | 121 | # because we do not have `SArray{Tuple{2,3}} <: StaticMatrix`.
|
103 | 122 | (::Type{SM})(I::UniformScaling) where {SM<:(StaticArray{Tuple{N,M}} where {N,M})} =
|
104 |
| - _scalar_matrix(Size(SM), SM, I.λ) |
| 123 | + SM(_scalar_matrix_elements(Size(SM), I.λ)) |
105 | 124 |
|
106 | 125 | # Construct a matrix with the scalar λ on the diagonal and zeros off the
|
107 | 126 | # diagonal. The matrix can be non-square.
|
108 |
| -@generated function _scalar_matrix(s::Size{S}, m_or_SM, λ) where {S} |
| 127 | +@generated function _scalar_matrix_elements(s::Size{S}, λ) where {S} |
109 | 128 | elements = Symbol[i == j ? :λ : :λzero for i in 1:S[1], j in 1:S[2]]
|
110 | 129 | return quote
|
111 | 130 | $(Expr(:meta, :inline))
|
112 | 131 | λzero = zero(λ)
|
113 |
| - _construct_similar(m_or_SM, s, tuple($(elements...))) |
| 132 | + tuple($(elements...)) |
114 | 133 | end
|
115 | 134 | end
|
116 | 135 |
|
|
0 commit comments