Использование матриц броненосца внутри класса

Я физик с небольшим опытом программирования с классами. Буду признателен, если кто-то сможет помочь с этим. Я успешно использовал массивы numpy внутри классов python, но здесь заблудился.

Мотивация проста. Мне нужно использовать класс с несколькими матрицами в качестве закрытых членов и выполнять над ними некоторые операции. Посмотрите на следующее.

#include<iostream>
#include<armadillo>

using namespace std;

class myclass{
    // a matrix
    double A[2][2];
public:
    int set_element(double);
};

int main(){
    myclass x;
    x.set_element(2.0);
}

int myclass::set_element(double num){
    // a function to assign a value to the first array element.
    A[0][0] = num;
    cout << A[0][0] << endl;
    return 0;
}

Это компилируется и работает правильно. Но если я попытаюсь использовать матрицу броненосца, ничего не получится.

#include<iostream>
#include<armadillo>

using namespace std;
using namespace arma;

class myclass{
private:
    // a matrix
    mat A(2,2);
public:
    int set_element(double);
};

int main(){
    myclass x;
    x.set_element(2.0);
}

int myclass::set_element(double num){
    //function to set the first element.
    A(0,0) = num;
    cout << A(0,0) << endl;
    return 0;
}

Когда я пытаюсь скомпилировать это, я получаю кучу или ошибки.

----@----:~/comp/cpp$ g++ dummy.cpp -larmadillo
dummy.cpp:10:15: error: expected identifier before numeric constant
dummy.cpp:10:15: error: expected ‘,’ or ‘...’ before numeric constant
dummy.cpp: In member function ‘int myclass::set_element(double)’:
dummy.cpp:22:14: error: no matching function for call to ‘myclass::A(int, int)’
dummy.cpp:22:14: note: candidate is:
dummy.cpp:10:13: note: arma::mat myclass::A(int)
dummy.cpp:10:13: note:   candidate expects 1 argument, 2 provided
dummy.cpp:23:22: error: no matching function for call to ‘myclass::A(int, int)’
dummy.cpp:23:22: note: candidate is:
dummy.cpp:10:13: note: arma::mat myclass::A(int)
dummy.cpp:10:13: note:   candidate expects 1 argument, 2 provided

Я уверен, что здесь мне не хватает какого-то ключевого аспекта; кто-нибудь, пожалуйста, укажите это.

Спасибо.!


person userJ    schedule 25.02.2014    source источник


Ответы (2)


Вам необходимо объявить матрицу броненосца в теле класса и инициализировать ее позже, например, в конструкторе класса. Поскольку матрицы броненосца не имеют размеров времени компиляции, размер матрицы относится к конструкции объекта, а не к его определению.

class myclass{
private:
    // a matrix - DECLARATION of a member variable
    mat A;
public:
    myclass() // Constructor
    : A(2, 2) { // Default matrix member variable initialization
    }

    // another constructor where you can supply other dimensions:
    myclass(int rows, int cols)
    : A(rows, cols) { // matrix member variable initialization
    } 

    int set_element(double);
};

Как только вы это поймете, есть некоторые изменения синтаксиса C++11, которые позволяют вам более элегантно написать случай конструкции по умолчанию, с синтаксисом, близким к тому, что вы хотели:

class myclass {
private:
    // a matrix - this syntax allows you to specify the default initialization parameters for this variable
    mat A {2, 2}; 
public:
    int set_element(double);
};

В качестве альтернативы вы можете использовать матрицу фиксированного размера во время компиляции, как предложено mtall ниже, что освобождает вас от необходимости устанавливать размер во время инициализации:

class myclass {
private:
    // a matrix - this syntax allows you to specify a compile-time size
    mat::fixed<2, 2> A; 
public:
    int set_element(double);
};
person Martin J.    schedule 25.02.2014
comment
Классы матриц Armadillo могут дополнительно использовать размеры времени компиляции — они называются матрицами фиксированного размера. Например mat::fixed<2,2> A; См. раздел расширенные конструкторы в документации. Точно так же векторы также могут иметь фиксированный размер: vec::fixed<10> v; - person mtall; 25.02.2014

Вы можете использовать код Мартина Дж., который использует матрицы динамического размера, или приведенный ниже код, который использует матрицы фиксированного размера.

Существуют плюсы и минусы использования матриц фиксированного размера. С одной стороны, фиксированные размеры могут позволить умному компилятору C++ (например, gcc) оптимизировать больше. С другой стороны, размер матрицы изменить нельзя, и выгоды от оптимизации полезны только для небольших матриц. Использование больших матриц фиксированного размера (т. е. больше 10x10 или 100 элементов) также может занимать память стека.

#include <iostream>
#include <armadillo>

using namespace std;
using namespace arma;

class myclass{
private:
   // a fixed-size matrix: allows more optimization
   // (generally recommended only for sizes <= 10x10)
   mat::fixed<2,2> A;
public:
   int set_element(double);
};

int main(){
  myclass x;
  x.set_element(2.0);
}

int myclass::set_element(double num){
  //function to set the first element.
  A(0,0) = num;
  cout << A(0,0) << endl;
  return 0;
}
person mtall    schedule 25.02.2014