C ++: продвинутая модель класса для матричного калькулятора - PullRequest
0 голосов
/ 01 мая 2019

Я делаю матричный калькулятор как проект для своего класса C ++ в колледже, и я не уверен, как разработать классы для него. Моя проблема заключается в том, что одной из особенностей этой программы является то, что разреженные и плотные матрицы должны храниться по-разному для эффективности памяти (плотные, как типичный двумерный массив или вектор, например, разреженный в формате CSR), но мне нужно разобраться оба типа одинаково.

До сих пор я думал о чем-то вроде абстрактного класса MatrixWrapper, который должен содержать все общие алгоритмы для сложения, умножения, GEM и так далее. И затем есть классы 'MatrixDense' и 'MatrixSparse', которые оба наследуют от 'MatrixWrapper' и поэтому имеют одинаковый интерфейс (как показано в коде ниже). Но вот где я застрял, потому что при таком подходе, когда я пытался реализовать алгоритмы в MatrixWrapper, я не знал, с какой из двух матриц я буду работать. Я просто не уверен, как решить эту проблему или даже может подойти правильно.

class MatrixWrapper {
  public:
    // shared algorithms
    /* for example

      void addMatrix ( const ??? &x ) {
        ...
      }

    */
}

class MatrixDense : public MatrixWrapper {
  public:
    //constructor, destructor, ...
  private:
    vector< vector<double> > matrix;
}

class MatrixSparse : public MatrixWrapper {
  public:
    //constructor, destructor, ...
  private:
    struct CSR {
      ...
    };
    CSR matrix;
}

Возможно, я думал о добавлении 2D-массива в MatrixWrapper вместе с абстрактным методом setValue (), а затем в MatrixSparse и MatrixDense каждый раз, просто устанавливая значения этого массива с помощью этого метода, а затем просто работая с этим 2D-массивом в MatrixWrapper, но я не уверен, как реализовать это или даже если это правильный подход.

1 Ответ

1 голос
/ 01 мая 2019

Реализация всех бинарных операторов с использованием функций, не являющихся членами. Либо глобальные функции, либо функции внутри несвязанного класса:

// Option 1
void add(
    MatrixWrapper& result,
    const MatrixWrapper& operand1,
    const MatrixWrapper& operand2);

// Option 2
struct WrapperForMatrixOperations // I don't know why you might want this class to exist
{
    static // or maybe not static
    void add(
        MatrixWrapper& result,
        const MatrixWrapper& operand1,
        const MatrixWrapper& operand2);
};

Причина в том, что ваш алгоритм, вероятно, вернет "плотную" матрицу при добавлении плотной и разреженной матрицы:

dense + sparse = dense
sparse + sparse = sparse
sparse + dense = dense <- problem!
dense + dense = dense

Это не может работать, если оно реализовано как функция, не являющаяся const.

Вы также должны решить, как вы хотите создать свои матрицы - возможно, каждая бинарная операция должна выделить новую матрицу и вернуть ее на shared_ptr?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...