开发者

c++ matrix calculations

I have created the following problem which (for now) is going to calculate the determinant or a matrix.( I will expand it that's why I input the dimensions and the matrices).

EDITED--->>> The problem which remains :

  • It doesn't recognize the variables "mat " in my functions.

error: ‘mat’ was not declared in this scope

 #include <iostream>
 #include <cstdio>
 #include <cstdlib> 
 #include <cmath>

using namespace std;

class matrix {
private:
int rows,columns;

public:
//constructor
matrix ()
{}
matrix(int _rows,int _columns) : rows(_rows),columns(_columns){
{
 int **mat=new int *[rows];
    for (int r = 0; r < rows; ++r)
        mat[r] = new int[columns];
}

}
//destructor
~matrix(){
for (int r = 0; r < rows; ++r)
        delete[] mat[r];
    delete[] mat;

}

//void allocate();
void getdata() {

cout <<"Enter number of rows :"<<endl;
cin >>rows;
cout <<"Enter number of columns : "<<endl;
cin >> columns;

}
void fill();
double determinant();
void showdata(){

}

};



int main()
{
matrix a;

a.getdata();
a.fill();
a.determinant();

    return 0;
}



//fills the matrix
v开发者_运维问答oid matrix ::fill(){

    for(int i=0;i<rows;i++) {
        for(int j=0;j<columns;j++){
        cout <<"Enter the elements in a line separated by whitespace :"<<endl;
        cin >>mat[i][j];
        }
    }

}
//calculate the determinant
double matrix :: determinant (){
    double det;
    det = mat[rows][columns]*mat[rows+1][columns+1] - mat[rows][columns+1]*mat[rows+1][columns];
    cout <<"The determinant of matrix is :"<<det<<endl;}


What you are trying to do is initialize mat to be an array of dynamic size. This cannot be done in, as your compiler tells you, a constant expression.

You must write a constructor for the matrix class which will take rows as a parameter and contain the mat=new int *[rows] line. Note that you'll also need to initialize each row of mat; your allocate method does this and should be called from the constructor.


The initialization of mat belongs into the constructor, say

matrix::matrix(int _rows, int _columns)
: rows(_rows)
, columns(_columns)
, mat(new int *[rows])
{
    for (int r = 0; r < rows; ++r)
        mat[r] = new int[columns];
}

Do not forget the destructor:

matrix::~matrix()
{
    for (int r = 0; r < rows; ++r)
        delete[] mat[r];
    delete[] mat;
}

This being said, I highly advice against inventing yet another "my great own matrix class library". Use something efficient and established such as Eigen.

Also, for containers, unless you have really good reasons, use some good class library for that. E.g. the standard library with std::vector and so on, or (even better in my taste): Qt classes like QVector.


Seeing that you've variable size for your matrix and that your matrix data is going to be in the heap, you've to initialize your matrix data in the constructor or by lazy instantiation. I had previously answered a question for creating a matrix. Here's the link to it. If you look in there you can observe that data is not initialised before the size of the matrix is known and as in your case it's created in the heap memory.

EDIT: C++ does not allow initialisation of member variables in the heap when they are declared. And in your case the size of the matrix is not known in the first place for mat to be created with the right size of memory. As mentioned by everybody in here, use the constructor to create the mat instance.


new operator dynamically allocates memory ( i.e., from the free store ). So, it should be part of any member function to assign its return address to a member variable in this example and not the part of class declaration. It can be a part of your getdata() member function.

And also, class requires a destructor because it is managing resources.

Edit 1 :

Problems -

  1. int **mat=new int *[rows];, is a local variable in the parameterized constructor and goes out of scope once the call to the constructor is done raising memory leaks.

  2. With the statement, matrix a;, the default constructor will be called. i.e., matrix::matrix(), the constructor with no arguments. However, you are making your initialization in the parameterized constructor.

To make everything work, try this -

class matrix
{
    int **mat;
    // ...

    public:
    matrix()
    {
        cout <<"Enter number of rows :"<<endl;
        cin >>rows;
        cout <<"Enter number of columns : "<<endl;
        cin >> columns;

        mat=new int *[rows];
        for (int i=0;i<rows;i++) {
            mat[i]=new int [columns];
        }
    }

    // And no more, getdata() member function is required. Avoid it's call in main()
};

Hope it helps !


With your immediate question:

mat appears to be a local variable in your constructor and not a class member i and j are local variables declared in fill() but not determinant()

There are other major issues:

  • Your matrix does not initialize rows or columns. These will have any random value and given they are signed ints, could even be negative. Your constructor might well throw bad_alloc

  • fill with what?

  • That isn't the correct formula to get a determinant, which in any case only applies to square matrices

  • You would be better off using vector rather than arrays and only one vector. Look at the C++ FAQ to see the simplest way to make a matrix.

    Assuming you do want it to be a matrix of int not double, declare "mat" this way:

    std::vector<int> mat;

Your constructor should be something like:

matrix::matrix (int r,int c) :
   rows(r), columns(c), mat(r*c)
{
    //body
}

Overload operator[] thus:

int* operator[](int r)
{
    return &mat[r*columns];
}

const int* operator[](int r) const
{
    return &mat[r*columns];
}

Note we have 2 of them. It is possible to implement one in terms of the other. Some also like to overload operator() to take 2 parameters, row and column, but the above will work.

You might prefer to use size_t rather than int for dimensions.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜