How should I implement a custom matrix object with certain symmetries?

I would like to implement an object that represents a 4x4 symplectic matrix. I'm using the nalgebra crate for this, but I'm not sure how to tackle the problem. Should I use a struct or a trait?

  • if I use a Symplectic trait, I could implement it for 4x4 Matrix structs from nalgebra, which would allow me to write generic functions that accept any 4x4 matrices (including symplectic ones), and functions that only accepts 4x4 matrices which are symplectic. I would have also all the various operations between matrices work for free for symplectic matrices, i.e. I can multiply two matrices, one or both being symplectic, without adding any new code. The problem is that I don't know how to enforce constraints on the entries of the symmetric matrix. Traits describe behaviour, not data, but a symmmetric matrix has constraits on its data. How can I be sure that a Matrix object implementing my Symplectic trait has its entries respect the symmetry?
  • if I instead use a struct, I can easily have an object Symplectic that stores only the needed data, and implement a function that returns a 4x4 Matrix object constructed from the data using the symplectic symmetry. The problem is that now I have to manually implement all operations between matrices and my Symplectic object, and I can no longer write functions which accept any 4x4 matrices including symplectic ones, because Matrix from nalgebra and my Symplectic struct are two different types. I could declare an empty trait and implement it for 4x4 Matrix and Symplectic just to be able to have common functions that work on both, but it seems a bit hacky. And the problem of having to implement all operations between matrices remain.

I think the only way to properly enforce constraints on data is to use a bunch of assert statements.