# Matrix multiplication with custom types

**URL:** https://discourse.julialang.org/t/matrix-multiplication-with-custom-types/25280
**Category:** New to Julia
**Tags:** question
**Created:** [June 13, 2019, 10:26pm UTC](https://discourse.julialang.org/t/matrix-multiplication-with-custom-types/25280 "2019-06-13T22:26:33Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![staticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/staticus/32/8903_2.png) [@staticus](https://discourse.julialang.org/u/staticus)
#### Post date: [June 13, 2019, 10:26pm UTC](https://discourse.julialang.org/t/matrix-multiplication-with-custom-types/25280/1 "2019-06-13T22:26:33Z")

</div>

Hey there.

So I’m very new to coding with Julia and am trying to get a handle on the “generalizability” of the language, as I’ll call it.

Below I created a Point strcut/class/? and defined the + and \* operations of two points. I want to figure out how to take this and make the last line work somewhat like regular matrix multiplication works. Just instead of scalars the entries of the resulting matrix would be Point’s. Could someone point me in the direction to look to do this?

```julia
import Base.+
import Base.*

struct Point
    x::Number
    y::Number
end

+(p1::Point, p2::Point) = Point(p1.x + p2.x, p1.y + p2.y)
*(p1::Point, p2::Point) = Point(p1.x * p2.x, p1.y * p2.y)

a = Point(1,1)
b = Point(2,2)
c = a + b

point_matrix = [Point(i, j) for i in 1:3, j in 4:6]
point_matrix

point_vector = [a; b; c]
point_vector

point_matrix * point_vector

```

Below is the error that is generated

MethodError: no method matching zero(::Point)  
Closest candidates are:  
zero(!Matched::Type{LibGit2.GitHash}) at /buildworker/worker/package\_linux64/build/usr/share/julia/stdlib/v1.1/LibGit2/src/oid.jl:220  
zero(!Matched::Type{Pkg.Resolve.VersionWeights.VersionWeight}) at /buildworker/worker/package\_linux64/build/usr/share/julia/stdlib/v1.1/Pkg/src/resolve/VersionWeights.jl:19  
zero(!Matched::Type{Pkg.Resolve.MaxSum.FieldValues.FieldValue}) at /buildworker/worker/package\_linux64/build/usr/share/julia/stdlib/v1.1/Pkg/src/resolve/FieldValues.jl:44  
…

Stacktrace:  
[1] generic\_matvecmul!(::Array{Point,1}, ::Char, ::Array{Point,2}, ::Array{Point,1}) at /buildworker/worker/package\_linux64/build/usr/share/julia/stdlib/v1.1/LinearAlgebra/src/matmul.jl:542  
[2] mul! at /buildworker/worker/package\_linux64/build/usr/share/julia/stdlib/v1.1/LinearAlgebra/src/matmul.jl:76 [inlined]  
[3] \*(::Array{Point,2}, ::Array{Point,1}) at /buildworker/worker/package\_linux64/build/usr/share/julia/stdlib/v1.1/LinearAlgebra/src/matmul.jl:50  
[4] top-level scope at In[12]:1

Also, if anyone could give me formatting tips or a link to a guide on how to make a better post that would be great!

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [June 13, 2019, 10:39pm UTC](https://discourse.julialang.org/t/matrix-multiplication-with-custom-types/25280/2 "2019-06-13T22:39:22Z")

</div>

Welcome to Julia!

So the error you’re running into is that it wants a `zero` function defined, which it uses at some point during the matrix multiplication algorithm. So it wants you to define a function `zero(::Point) = ...` that returns a zero object for the `Point` type, i.e. something so that that `x + zero(Point) == x` whenever `x` is a `Point` (in other words, `zero(T)` should return the additive identity for things of type `T`, but it doesn’t know what this is for `Point`s, so it wants you to define the method).

Formatting tips: [PSA: how to quote code with backticks](https://discourse.julialang.org/t/psa-how-to-quote-code-with-backticks/7530)

General posting tips: [Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757)

---

<div class="post-metadata">

### Author: ![staticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/staticus/32/8903_2.png) [@staticus](https://discourse.julialang.org/u/staticus)
#### Post date: [June 13, 2019, 10:51pm UTC](https://discourse.julialang.org/t/matrix-multiplication-with-custom-types/25280/3 "2019-06-13T22:51:22Z")

</div>

Thanks for that! Still getting used to understanding the errors in Julia. I added the lines

```julia
import Base.zero
zero(x::Point) = Point(0,0)

```

to the code and it worked.

Is there a place that indicates the types of functions I have to import from Base to get them to work like this? I’ll look through the docs a bit.

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [June 13, 2019, 11:06pm UTC](https://discourse.julialang.org/t/matrix-multiplication-with-custom-types/25280/4 "2019-06-13T23:06:05Z")

</div>

The answer is “each of them that you use” (any function from Base that you want to override requires that you do one of two things)

```julia
import Base: +, *, zero

zero(x::MyType) = ...

```

or (does not require the import statement)

```julia
Base.zero(x::MyType) = ...

```

also, your type will work more quickly if you define it this way

```julia
struct Point{T<:Real}
    x::T
    y::T
end

```

see the docs [Constructors · The Julia Language](https://docs.julialang.org/en/v1.1/manual/constructors/#Parametric-Constructors-1)

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [June 13, 2019, 11:21pm UTC](https://discourse.julialang.org/t/matrix-multiplication-with-custom-types/25280/5 "2019-06-13T23:21:16Z")

</div>

Just to add, with the parametric definition (`struct Point{T <: Real}`), you would want to define `zero` as

```julia
import Base.zero
zero(::Point{T}) where {T} = Point(zero(T), zero(T))

```

so that way you get `Point`’s with the right numeric type:

```julia
julia> zero(Point(1.0, 2.0))
Point{Float64}(0.0, 0.0)

julia> zero(Point(1, 2))
Point{Int64}(0, 0)

```

This actually illustrates one of the advantages of the parametric definition; without it, you don’t know ahead of time what the numeric types of `p.x` and `p.y` are for a `Point` `p`, but in the parametric case you do since you have access to the parameter `T` to use in `zero`.

(You could define `zero(p::Point) = Point(zero(p.x), zero(p.y))` in the non-parametric case, but this involves a runtime lookup to figure out the type of `p.x` in order to choose the right `zero` method to use when you call `zero(p.x)`, whereas in the parametric case it’s all done at compile time.)

---

<div class="post-metadata">

### Author: ![staticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/staticus/32/8903_2.png) [@staticus](https://discourse.julialang.org/u/staticus)
#### Post date: [June 13, 2019, 11:29pm UTC](https://discourse.julialang.org/t/matrix-multiplication-with-custom-types/25280/6 "2019-06-13T23:29:18Z")

</div>

Thanks for the extra tidbit Jeffrey!

---

<div class="post-metadata">

### Author: ![staticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/staticus/32/8903_2.png) [@staticus](https://discourse.julialang.org/u/staticus)
#### Post date: [June 13, 2019, 11:29pm UTC](https://discourse.julialang.org/t/matrix-multiplication-with-custom-types/25280/7 "2019-06-13T23:29:56Z")

</div>

Thanks for the detailed explanation Eric! I’ll be sure to look this up.
