-2

My main trouble comes from void setWSparsity(const ExponentialSparsityTemplate(& t)(double wSparsity, double SparsityExp));, t.sparsity(p, _decay), and the "SparsityTemplate" of which there are more than one kind. I either get the header definition to compile and not the code or vice-versa. How should these definitions be properly setup?

The example below does not compile but demonstrates what I am struggling with. I would like to have 2 or more different SparsityTemplates and properly use const and private variables. Initialization was missing and I attempted to add that. The sample takes code from a linear algebra library, so namespaces have been removed.

_Ws as does _t comes from a linear algebra namespace

#include <cmath>
#include "matrix.h"

/**
 * Sparsity template with exponential increase depending on the time
 * index p.
 */
class Deconvolver
{ 

 class SparsityTemplate
    {
    public:
        virtual double sparsity(double p) const;
        virtual ~SparsityTemplate() = default;
    }; 
class ExponentialSparsityTemplate:  public SparsityTemplate
    {
    public:
        ExponentialSparsityTemplate(double sparsity, double sparsityexp) :
            _sparsity(sparsity), _decay(sparsityexp) {}
        virtual ~ExponentialSparsityTemplate() = default;
        void setWSparsity(const ExponentialSparsityTemplate(& t)(double wSparsity, double SparsityExp));
        

    private:
        double _sparsity = 0;
        double _decay = 0;
    };
void setWSparsity(const ExponentialSparsityTemplate(& t)(double wSparsity, double SparsityExp));
};
    


int main() 
{
    double wSparsity = 0.01;
    double wSparsityExp = 1.7;
    // The Matrix is 10 x 5 and is filled by a generator function
    Matrix x(10, 5, );
    Deconvolver d(x, 10, 3);
    d.setWSparsity(
       ExponentialSparsityTemplate(wSparsity, wSparsityExp));
}

void Deconvolver::setWSparsity(
        const ExponentialSparsityTemplate(& t)(double wSparsity, double wSparsityExp))
{
    
_sparsity = wSparsity * std::pow(sparsityexp, p);
for (unsigned int p = 0; p < _t; ++p)
    {
        for (unsigned int j = 0; j < _wS[p]->cols(); ++j)
        {
            for (unsigned int i = 0; i < _wS[p]->rows(); ++i)
               _wS[p]->at(i, j) = t.sparsity(p, _decay);
        }
    }

}
Sildeag
  • 74
  • 9
  • Your definition of `setWSparsity` is a global function rather than a member of `ExponentialSparsityTemplate`? Without a [mre] and the full error message it's difficult to know what your problem is – Alan Birtles Aug 10 '22 at 21:50
  • Alan thanks for your comment: `error: request for member ‘sparsity’ in ‘t’, which is of non-class type ‘const Deconvolver::ExponentialSparsityTemplate(double, double)’ 221 | _wS[p]->at(i, j) = t.sparsity(p, _decay);` I don't know how to create this relationship. The other type of errors are related to `const` and the "Templates". – Sildeag Aug 10 '22 at 22:44
  • Looks/sounds like you want a strategy pattern. – Taekahn Aug 11 '22 at 00:28
  • Yes. Similar code works for `const Deconvolver::DefaultSparsityTemplate(double)` with no issue. It is just how to go from there to including the `_decay`, – Sildeag Aug 11 '22 at 01:05
  • This was helpful: https://stackoverflow.com/questions/7405740/how-can-i-initialize-base-class-member-variables-in-derived-class-constructor – Sildeag Aug 11 '22 at 23:41

1 Answers1

1

The problem was a combination of things:

  1. C++ Virtual function being hidden
  2. https://www.learncpp.com/cpp-tutorial/constructors-and-initialization-of-derived-classes/ In my project some virtual functions had used the same name as those in the initialization list and as I was trying to initialize and remove unused variables, I had disturbed hidden virtual functions which I hadn't fully understood. The exact same names being used made the code very difficult to follow so I went back to the original code and more slowly applied name changes to private variables and member initialization lists, and then made changes to virtual functions. I used () not {} for parameters in point 2 but the example was helpful as the same name was not used.
Sildeag
  • 74
  • 9