# How to define a new matrix type?

**URL:** https://discourse.julialang.org/t/how-to-define-a-new-matrix-type/112098
**Category:** New to Julia
**Tags:** question, type, struct, matrix
**Created:** [March 25, 2024, 5:21pm UTC](https://discourse.julialang.org/t/how-to-define-a-new-matrix-type/112098 "2024-03-25T17:21:00Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![homocomputeris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/homocomputeris/32/8933_2.png) [@homocomputeris](https://discourse.julialang.org/u/homocomputeris)
#### Post date: [March 25, 2024, 5:21pm UTC](https://discourse.julialang.org/t/how-to-define-a-new-matrix-type/112098/1 "2024-03-25T17:21:00Z")

</div>

How do I define a thin wrapper type around a matrix?

I assumed that from LinearAlgebra should do what I want.  
However, it throws an error:

```julia
struct MyMatrix{T,S<:AbstractMatrix{<:T}} <: AbstractMatrix{T}
    data::S

    function MyMatrix{T,S}(data) where {T,S<:AbstractMatrix{<:T}}
        new{T,S}(data)
    end
end

A = rand(2,2)

MyMatrix(A)
ERROR: MethodError: no method matching MyMatrix(::Matrix{Float64})
Stacktrace:
 [1] top-level scope
   @ REPL[6]:1

```

How should it be modified to wrap any matrix into `MyMatrix` type?

---

<div class="post-metadata">

### Author: ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)
#### Post date: [March 25, 2024, 5:25pm UTC](https://discourse.julialang.org/t/how-to-define-a-new-matrix-type/112098/2 "2024-03-25T17:25:32Z")

</div>

See [the array interface specification](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array). For most functions, you probably just want to pass through to the wrapped matrix. For example, you probably want to define `Base.size(x::MyMatrix) = size(x.data)`.

As for the error you’re seeing there, it’s because the only defined constructor requires you to specify `{T,S}`. You probably can just delete your inner constructor. If that doesn’t work, then define an outer constructor `MyMatrix{x::S} where S<:AbstractMatrix{T} where T = MyMatrix{T,S}(x)` (or something like that, I might have messed up where the `where`s go).

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [March 25, 2024, 8:24pm UTC](https://discourse.julialang.org/t/how-to-define-a-new-matrix-type/112098/3 "2024-03-25T20:24:15Z")

</div>

First, if you want to use `MyMatrix` without parameters, you need to define a constructor that has no parameters. Then, you need to implement the interface that mikmoore pointed out. In particular, `Base.size` and `Base.getindex`. Here’s an example.

```julia-repl
julia> begin

       struct MyMatrix{T,S<:AbstractMatrix{<:T}} <: AbstractMatrix{T}
           data::S

           function MyMatrix(data::S) where {T, S<:AbstractMatrix{<:T}}
               new{T,S}(data)
           end
       end
       Base.size(m::MyMatrix) = size(m.data)
       Base.getindex(m::MyMatrix, I...) = getindex(m.data, I...)

       end

julia> M = MyMatrix(rand(2,2))
2×2 MyMatrix{Float64, Matrix{Float64}}:
 0.600174 0.638277
 0.315073 0.000486425

julia> M^2
2×2 Matrix{Float64}:
 0.561313 0.383388
 0.189252 0.201104

```
