In writing a numerical library there is a unavoidable tension between completeness and simplicity. By completeness I mean the ability to perform operations on different objects so that the group is "closed". In mathematics objects can be combined and operated on in an infinite number of ways. For example, I can take the derivative of a scalar field wrt a vector and the derivative of a vector field wrt a scalar (along a path).
There is a definite tendency to unconsciously try to reproduce this in a numerical library, by adding new features one by one. After all, it is always easy enough to support just one more feature.... so why not?
Looking at the big picture, no-one would start out by saying "I want to be able to represent every possible mathematical object and operation using C structs" -- this is a strategy which is doomed to fail. There is a limited amount of complexity which can be represented in a programming language like C. Attempts to reproduce the complexity of mathematics within such a language would just lead to a morass of unmaintainable code. However, it's easy to go down that road if you don't think about it ahead of time.
It is better to choose simplicity over completeness. In designing new parts of the library keep modules independent where possible. If interdependencies between modules are introduced be sure about where you are going to draw the line.