Matrix operations with custom number type

Given this definition of a custom number type:

struct Node <: Number
end
export Node

Base.:*(a::Node, b::Node) = Node()
Base.:+(a::Node, b::Node) = Node()

why does this

julia> a = Node();b=Node();

julia> A = [a b;a b]
2×2 Matrix{Node}:
 Node()  Node()
 Node()  Node()

julia> bvec = [a,b]
2-element Vector{Node}:
 Node()
 Node()

julia> A*b
2×2 Matrix{Node}:
 Node()  Node()
 Node()  Node()

give a different result than this:

julia> [a b;a b]*[a,b]
ERROR: MethodError: no method matching Node(::Int64)

Closest candidates are:
  (::Type{T})(::T) where T<:Number
   @ Core boot.jl:792
  Node()
   @ MatrixX C:\tmp\Matrix\src\MatrixX.jl:4
  (::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number}
   @ Base char.jl:50
  ...

Stacktrace:
 [1-6] ⋮ internal
     @ Base, LinearAlgebra, Unknown
   [7] *(A::Matrix{Node}, x::Vector{Node})
     @ LinearAlgebra C:\Users\seatt\.julia\juliaup\julia-1.9.1+0.x64.w64.mingw32\share\julia\stdlib\v1.9\LinearAlgebra\src\matmul.jl:56
   [8] top-level scope
     @ REPL[12]:1
Use `err` to retrieve the full stack trace.

Is there some other Base method that has to be defined on Node to make this work?

It looks like you’re multiplying A by b instead of bvec, which may be doing scalar multiplication instead of matrix-vector multiplication. Does A * bvec fail?

You need to define Base.zero(::Node) = Node().

3 Likes

my bad. A*bvec fails with the same error message. Defining Base.zero solved the problem. That is an obscure error message though. Is there a doc section that details which Base methods should be defined for custom number types?

The error message definitely could be better. Numbers · The Julia Language has the functions that you might want to overload (note that for many number types a lot of them will not be applicable). I would recommend looking at the list of functions and seeing which make sense for your type and implementing enough of them to get them to work (many have sane fallbacks i.e. iszero(x) defaults to isequal(x, zero(x))).

1 Like