I’m trying to generate a struct, and one of the of the elements of the struct depends on a parameter of the class. I’m not really sure how to do it tho
Example of what I’m doing
struct SpectralDiscretization1D
Space
kind #:Fourier, :Cheb1, :Cheb2, :Leg
N #Number of points
A #Matrix needed for change of coordinates, can it be FFT, DCT, LegMatrix, etc.
A⁻¹ #Inverse of A
if kind == :Cheb1
DCT = FFTW.plan_r2r(ones(N) ,FFTW.REDFT00, 1, flags = FFTW.MEASURE)
SpectralDiscretization1D(Space, kind, N) = new(Space, kind, N, DCT, DCT)
A = FFTW.plan_r2r(ones(N) ,FFTW.REDFT00, 1, flags = FFTW.MEASURE)
A⁻¹ = A
elseif kind == :Cheb2
DCT = FFTW.plan_r2r(ones(N) ,FFTW.REDFT10, 1, flags = FFTW.MEASURE)
SpectralDiscretization1D(Space, kind, N) = new(Space, kind, N, DCT, DCT)
end
end
I want to be able to give more than only 2 options (and hopefully not everything in one line) and I’m not sure how to extend the example of the documentation
Sorry for nit-picking, but getting the terminology straight makes it a lot easier to find an actual solution to your problem.
parameters (of a type/struct): see here Types · The Julia Language
I think what you are referring to in the original question is the fields of the struct (like kind, N, etc.) This difference is important, because perhaps what you really want to use are parameters
class: doesn’t exist, but also doesn’t matter – structs also have constructors and as @Tomas_Pevny said, an inner constructor gives you the ability to compute the values of some fields based on the inputs to the constructor
Here is how that might work in your case:
struct SpectralDiscretization1D
Space
kind
N
A
A⁻¹
# Inner constructor – works like any other function except that it has to be in the struct block and should return some `new(...)` object
function SpectralDiscretization1D(Space, kind, N)
# Here goes your logic that constructs the fields based on, e.g. kind and N (or anything else
if kind == :Cheb1
DCT = FFTW.plan_r2r(ones(N) ,FFTW.REDFT00, 1, flags = FFTW.MEASURE)
A = FFTW.plan_r2r(ones(N) ,FFTW.REDFT00, 1, flags = FFTW.MEASURE)
A⁻¹ = A
return new(Space, kind, N, A, A⁻¹)
elseif kind == :Cheb2
DCT = FFTW.plan_r2r(ones(N) ,FFTW.REDFT10, 1, flags = FFTW.MEASURE)
return = new(Space, kind, N, DCT, DCT)
end
end
end
Note that defining your own inner constructors will “overwrite” the default constructor. This might be what you want, but you can also just make the constructors “outer constructors” instead.
Just a tip: it might be worth fixing the type of the fields of your struct to get more optimized compiled versions of your code.