For my own use, I'd like to develop a small Vector and a Matrix class, independent of some big libraries that exist out there.
My question is:
Should Vector and Matrix stay two independent entities or should I derive a Vctor frm a Matrix or a Matrix from a Vector?
Any response is as always greatly appreciated. :)

## All 9 Replies

I don't know anything about those objects but my tip would be to consider the Liskov substitution principle in making your decision.

commented: Thanks for the tip. +15

Hmm. Of the top of my head, I'd say it really depends on what features you plan to support. If there's a huge amount of intersection between the two, I might choose to implement the vector as a composition/specialization of a matrix of 1xN or Nx1. Alternatively, a matrix may be a construction of vectors if that turns out to be more efficient.

I might not even split the two at all and let the caller use the matrix as a vector if there aren't any vector-specific operations (or manually construct a matrix out of vectors, but that seems less useful mathematically).

It's personal preference, of course, but I tend not to rely on inheritance unless necessary. Composition or careful generalization tends to cover most of my needs.

commented: Great help. +15

After reading about the Barbara Liskov principle, where I also found this interesting article and what decepticon had to say, I really got enlighted about OO again! A vector although showing some resemblance with a matrix (you could call it a 1,N or N,1 matrix) is in fact a totaly different object. It was like I was trying to construct an inheritance between a rope and a snake!
Thanks guys :)

Thats a good looking pdf - shall have a proper read later.

It's normally called the "Liskov substitution principle" but I like the "Barbara Liskov Principle".

We would have to change SOLID to SOBID though which doesn't have quite the same punch!

It worries me that much of this discussion is about the difficulty or efficiency of inheriting either way. And although Liskov is 100% relevant, it's a heavyweight way of expressing the absolute basic English definition:
"inheritance" is an is-a relationship
If a Vector is-a Matrix then Vector is a subclass of Matrix, and vice-versa. If neither is true then there is no subclass relationship.
Obviously a Matrix is-not-a Vector, so Matrix cannot possibly be a subclass of Vector.
However you can assert that a Vector is-a Matrix (single column or single row) so you could, if you thought it useful, have Vector as a (specialised) subclass of Matrix.

commented: Thanks for your tip! +15

@JamesCherrill: Thanks for your answer! In a way this is what I had in mind, but I started doubting. I guess my comparision of a snake and a rope is perhaps a bit over the line...

I think that it makes some sense to consider a Vector as a subclass of (derived from, special kind of) Matrix. For example, Matlab creates vectors as matrices (as Nx1), and treats any matrix with one dimension that is 1 as a vector, i.e., it doesn't even "subclass" them, it simply creates a Nx1 matrix when you create a vector. This is an even stronger approach, by saying not only that a vector is a kind of matrix, but by saying that a vector is just a matrix.

But this "vectors are matrices" approach is convenient but it also has its drawbacks. Mathematically, vectors have a lot more useful properties than matrices, and these become awkward to express when you use this approach. Just look at some of the more awkward Matlab functions that try to deal with this problem, e.g., particularly bad examples is the norm or max functions, where you have a single function that has different behaviours and parameters depending on the type (vector or matrix) of the "matrix" involved. This kind of stuff creates unnecessarily complicated interfaces because all this stuff has to be (1) documented in details and (2) checked at run-time, and you need to figure out if there are any reasonable fallbacks or merges to be done (e.g., is the Frobenius norm of a Nx1 matrix the same as the Euclidean norm?).

I would not recommend doing what Matlab has done, as I consider it one of its design flaws (it's one of the most obvious Fortran'ism of Matlab). At the very least, vectors and matrices should be two different types. Now, it becomes a question of subclassing or not.

Personally, I would not recommend subclassing, mainly because object-oriented programming is woefully inadequate for this particular kind of work. Nearly every math operation you can do with matrices and vectors will turn into a double / multiple dispatching problem, which OOP techniques, like inheritance and virtual functions, are not appropriate for. Furthermore, the knowledge of whether things are vectors or matrices is a knowledge you nearly always have at compile-time (it's static information) and therefore should be strongly encoded in the type system and dispatched statically (through overloading, templates, generics, .. whatever facilities your language provides, and if not, fall-back to C'isms like what Blas does with its crazy complicated naming conventions).

As you might have guessed, I've wrestled with this problem at great lengths, and in my early days, I tried about every approach you could think of (incl. the "vectors are matrices" approach of Matlab and the OOP "vector is a kind of matrix" approach). My conclusion, from experience, is similar to what many of the more successful linear-algebra libraries have also settled for, which is to use generic programming. This means that vectors and matrices (and various special types of matrices) are all completely distinct types / classes, and all the functionality they might have in common are shared through functional overloads and generic algorithms that are statically multi-dispatched based on their types and compliance to certain generic concepts. This is really the only scalable approach. This is the approach I use in my linear algebra library, and it is also the approach in other successful modern linear algebra libraries like Boost.uBlas and Eigen.

The fundamental reason why this is the best approach is because generic programming maps directly to the way Group Theory works in mathematics, and this is also the way mathematics describes the relationships between things like scalars, vectors, matrices, tensors, and geometric entities (like manifolds), and also between operators (inner / exterior products, norms, exponential maps, etc...). This makes the design of a generic library for linear algebra very natural, both to create and to use, because the correspondance with its mathematical formalism is direct.

If you are stuck in one of those "training wheels" languages that only allow you to create pure object-oriented attrocities, then you might be able to make do with mixins or interfaces (as in, Java-style "interfaces"). But I'm not sure what to suggest in this department, I don't really have experience with these "compensate for the limitations of OOP" design patterns. You are also going to be hitting snags with multiple-dispatch problems, which is where interfaces could probably help, I hope, as a poor-man's alternative to generic concepts.

I know that I'm probably making things much harder for you by telling you all this. But hey... there's no simple answer to this. Things also depend heavily on what you intend to do with the library, and the magnitude of it.

commented: You make me happy! +15
commented: Outstanding contribution. +15

Amazing contribution! :o)

I would also add that, as some have pointed out, it might be useful to be able to see a vector as a matrix and vice versa, for certain operations. If this is needed, the preferred approach is to use adaptors which have the advantage of being more explicit about the decision to treat a vector as a matrix and such, which prevents certain pitfalls that arise from implicit conversions that may not be what the user wants or expects. Common adaptors are "matrix view of a vector" (treat a vector as a Nx1 or 1xN matrix, or a NxN diagonal matrix), "matrix view of matrix" (treat a part of a larger matrix as a smaller matrix), and "matrix slice" (treat a row or column of a matrix as a vector). You can see those types of adaptors in most linear algebra libraries (like all those I linked to, including mine).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.