Struct & inner constructor

I’m trying to create a struct with an inner constructor to check some dimensions… Basic structure (let’s call it TEST) works:

using Polynomials
#
struct TEST{T}
  N::Matrix{Poly{T}}
  D::Matrix{Poly{T}}
end

This works (although I could introduce a show method):

julia> num = Poly.(fill([1,1],2,3));
julia> den = Poly.fill([1,1],2,2));
julia> TEST(num,den)
TEST{Int64}(Poly{Int64}[Poly(1 + x) Poly(1 + x) Poly(1 + x); Poly(1 + x) Poly(1 + x) Poly(1 + x)], Poly{Int64}[Poly(1 + 2*x + x^2) Poly(1 + 2*x + x^2); Poly(1 + 2*x + x^2) Poly(1 + 2*x + x^2)])

Next, I’d like to insert a test of dimensions of N and D to make sure that the description is correct/that N and D are compatible. I’m trying with the following:

struct TEST1{T}
    N::Matrix{Poly{T}}
    D::Matrix{Poly{T}}
    #
    function TEST1{T}(N::Matrix{Poly{T}},D::Matrix{Poly{T}}) where T <: Number
        n1,n2 = size(N)
        d1,d2 = size(D)
        if d1 != d2
            error("D matrix must be square")
        end
        if (n2 != d1) && (d2 != n1)
            error("N,D dimensions are incompatible")
        end
        new{T}(N,D)
    end
    #
end

and then get an error message during construction:

julia> TEST1(num,den)
MethodError: no method matching TEST1(::Array{Poly{Int64},2}, ::Array{Poly{Int64},2})

Stacktrace:
 [1] top-level scope at In[49]:1

This is my first attempt of a struct, so I assume the solution is trivial, but…
Questions

  1. What do I do wrong?
  2. What is the simplest inner constructor to achieve what I want?

You would need to call TEST1{T}(...) (with an explicit T).

One solution is defining a method that dispatches to this, eg

TEST1(N::Matrix{Poly{T}},D::Matrix{Poly{T}}) where T = TEST1{T}(N, D)

the other one is defining your inner constructor without the first {T}. I would suggest the latter if you get the T anyway from the arguments.

3 Likes

Thanks! The following seems to work…

struct TEST1{T}
    N::Matrix{Poly{T}}
    D::Matrix{Poly{T}}
    #
    function TEST1(N::Matrix{Poly{T}},D::Matrix{Poly{T}}) where T <: Number
        n1,n2 = size(N)
        d1,d2 = size(D)
        if d1 != d2
            error("D matrix must be square")
        end
        if (n2 != d1) && (d2 != n1)
            error("N,D dimensions are incompatible")
        end
        new{T}(N,D)
    end
    #
end

I’ll check it a little bit more, though.