Amy Cohen
Amy Cohen

Reputation: 109

Matrix - return and pass as parameter c++

I'm trying to use clear functions to do a matrix multiplication with random generated values. Therefore I'm hoping to use a function(mat_def) to generate the matrices and another function(mat_mul) to multiply them when the matrices are sent as parameters.

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace std;

double mat_def(int n) //how to return the matrix
{
    double a[n][n];

    double f; 

    for(int i=0; i<n;  i++)
    {
        for(int j=0; j<n; j++)
        {
            f= rand();
            cout<<f ;
            a[i][j]=f;
        }

    }

    return 0;
}


double mat_mul( int n, double a[n][n], double b[n][n]) //how to send matrix as parameter
{
    return 0;
}


int main()
{
    /* initialize random seed: */
    srand (time(NULL));
    mat_def(10); 
}

Upvotes: 1

Views: 1867

Answers (3)

user4581301
user4581301

Reputation: 33932

Returning the raw allocation is a sucker bet. You need to manage all of the memory allocated yourself and pass it around with the matrix size parameters.

Why suffer? Use a matrix class

template<class Type>
class Matrix{
    int rows;
    int cols;
    std::vector<type> data;
public:
    Matrix(int row, int col):rows(row), cols(col), data(rows*cols)
    {
        // does nothing. All of the heavy lifting was in the initializer
    }
    // std::vector eliminates the need for destructor, assignment operators, and copy 
    //and move constructors.
    //add a convenience method for easy access to the vector
    type & operator()(size_t row, size_t col)
    {
        return data[row*cols+col];
    } 
    type operator()(size_t row, size_t col) const
    {
        return data[row*cols+col];
    } 
};

Usage would be

Matrix<double> mat_mul(const Matrix<double> &a, const Matrix<double> &b) 
{
    Matrix<double> result;
    // do multiplication 

    return result;
}

int main()
{
    /* initialize random seed: */
    srand (time(NULL));
    Matrix<double> matA(10, 10); 
    matA(0,0) = 3.14; // sample assignment
    matA(9,9) = 2.78;
    double x = matA(0,0) * matA(9,9)
    Matrix<double> matB(10, 10); 

    Matrix<double> matC = mat_mul(matA, matB) ;
}

More functionality, such as construction from an initializer list, can be added to the class to make your life easier. You can also specify an operator * overload for Matrix and use that in place of mat_mul if you chose. Read Operator overloading for more on that option.

Upvotes: 1

user8038009
user8038009

Reputation:

I assume your problem is to define 2-D array and then pass it to mat_mul function to multiply the matrices. And the rest will be quite simple.

Defining the 2-D array(considering memory needs are known at run time):

    int rows,cols;
    cin >> rows;
    cin >> cols;

    int **arr = new int*[rows];          // rows X cols 2D-array 
    for(int i = 0; i < rows; ++i) {
        arr[i] = new int[cols];
    }

You can define another 2-D array exactly the same way with required rows and column.

now, Passing the 2-D array to function:

void mat_mul(int **arr1, int **arr2, int m, int n, int p, int q){
    //define a 2-D array to store the result
    //do the multiplication operation
    //you could store the result in one of the two arrays
    //so that you don't have to return it 
    //or else the return type should be modified to return the 2-D array
}

example:

void display(int **arr, int row, int col){
    for (int i=0; i<row; i++){
        for(int j=0;j<col; j++){
            cout << arr[i][j] << '\t';
        }
        cout << endl;
    }
}

Delete the memory if not required anymore with the following syntax:

for(int i=0; i<rows; i++){
  delete[] array[i];
}
delete[] array;

hope this will be sufficient to get your work done!

there is already an answer on how to return a 2-D array on SO. Check the link below.

https://stackoverflow.com/a/8618617/8038009

Upvotes: 1

NastyDiaper
NastyDiaper

Reputation: 2558

Here's a nice, standard C++ Matrix template for you.

Matrix.h

#include <vector>

class Matrix
{
    class InnerM
    {
        private:
           int ydim;
           double* values;

        public:
            InnerM(int y) : ydim(y)
            {
                values = new double[y];
            }

            double& operator[](int y)
            {
                return values[y];
            }
    };

    private:
       int xdim;
       int ydim;

       std::vector<InnerM> inner;

    public:

       Matrix(int x, int y) : xdim(x), ydim(y), inner(xdim, InnerM(ydim))
       {
       }

       InnerM& operator[](int x)
       { 
           return inner[x];
       }
};

All the memory leaks are there for you but you get the idea. From here you can handle the multiplication by overiding ::operator*() in the Matrix class.

Upvotes: 2

Related Questions