1

I'm a physicist working on a scientific code. Apologies if this is a routine question: it may well have been answered before, but I don't have the software engineering background to quite tell.

Basically, the code needs to perform a large number of matrix multiplications by a small number of different matrices. Constructing the matrices in the first place is very expensive, so I'd like them to persist between uses. However, the class which does the multiplication has no way of knowing what the matrices willl be during its initialization. They will vary substantially over its lifetime, and the same matrix will generally be used by multiple instances of the multiplication class.

It seems to me that the Singleton pattern applies in this situation: we can create a pool of matrices, keyed by whatever distinguishes them from one another. Then, the multiplication classes can access that pool whenever it needs a matrix.

Here's a sketch of what I have in mind:

//SingletonDictionary.hpp class SingletonDictionary : private NonCopyable { public: void Clear(); //Calls member variable destructors. ~SingletonDictionary() { Clear(); } private: friend SingletonDictionary& TheSingletonDictionary(); SingletonDictionary() {}; //Only the friend can make an instance. //Retrieve searches through the key vectors for a match to its //input. In none is found, the input is added to the key vectors, //and a new Value is constructed and added to the ValueVector. //In either case the ValueVector is returned. std::vector<double>& Retrieve(const int key1, const int key2); std::vector<int> mKey1; std::vector<int> mKey2; std::vector<double> mValue; } //SingletonDictionary.cpp SingletonDictionary& TheSingletonDictionary() { static SingletonDictionary TheSingleton; return TheSingleton; } //DoMatrixMultiply.cpp void ApplyTransformation(std::vector<double> data){ const int key1 = data.size()[0]; const int key2 = data.size()[1]; SingletonDictionary TheSingletonDictionary(); std::vector<double> TransformMatrix = TheSingletonDictionary.Retrieve(key1, key2); DGEMM("N", "N", data.Data(), TransformMatrix.Data(),.....); } 

NonCopyable is an abstract base class that disables the copy constructor, etc.

I'm wondering if this is an appropriate circumstance for this pattern. If not, what else might work?

1
  • 1
    You almost never want a Singleton. Commented Nov 29, 2015 at 22:17

1 Answer 1

2

A singleton is a global variable with sugarcoating, for most intents and purposes. Global variables are of course useful at times, but they also can be a cause of problems (because there is no way to have more than one insance).

I personally would consider having a class that holds these values (perhaps non-copyable), but making it a (reference) member of the actual calculation and more explicit that it is being used. This would also allow you to use more than one if you ever need to have TWO (or more) of these objects, rather than then having to rewrite the code to handle that case.

Sign up to request clarification or add additional context in comments.

2 Comments

The problem with this is that multiple instances of the calculation might need the same matrix. Or is there a way around that?
Then pass in the same object. My point is that a singleton can only ever be one - there's nothing preventing you from using ONE object always, even if it's stored as a reference in a dozen places. I had a similar issue when I created my Parser object in my compiler - I thought I only ever needed one, but I then needed to implement "Modules", which requires a "fresh" Parser. So sometimes, being able to create a second, third, fourth instance is helpful, and storing a reference to an instance typically costs less than calling a function that returns a static instance.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.