matrix copy problem

Y

Yudan Yi

I have a problem to copy (assign) a matrix to another matrix. Curreny, I
know copy the number using loops, while it will take some time, I wonder if
there have faster method. The following code explain my situation detailed.

double ** matrixa, **matrixb;
int nrow = 10, mcol = 10;
matrixa = initmatrix(nrow, mcol); // allocate memory a
matrixb = initmatrix(nrow, mcol); // allocate memory b
// copy a => b
for (int i=0;i<nrow;i++)
for (int j=0;j<mcol;j++)
matrixb[j] = matrixa[j];
freematrix(matrixa, nrow, mcol); // free memory
freematrix(matrixb, nrwo, mcol); // free memory


I want to find another way to copy the data from a => b without loop all the
data.

Thanks
 
V

Victor Bazarov

Yudan Yi said:
I have a problem to copy (assign) a matrix to another matrix. Curreny, I
know copy the number using loops, while it will take some time, I wonder if
there have faster method. The following code explain my situation detailed.

double ** matrixa, **matrixb;
int nrow = 10, mcol = 10;
matrixa = initmatrix(nrow, mcol); // allocate memory a
matrixb = initmatrix(nrow, mcol); // allocate memory b
// copy a => b
for (int i=0;i<nrow;i++)
for (int j=0;j<mcol;j++)
matrixb[j] = matrixa[j];


Without knowing what 'initmatrix' does, it's hard to be certain, but this

for (int i=0; i<nrow; i++)
memcpy(matrixb, matrixa, mcol*sizeof(double));

could be just a bit faster. Of course, the real C++ way would be to use
'std::copy':

for (int i=0; i<nrow; i++)
std::copy(matrixa, matrixa+mcol, matrixb);

.. It's up to you to check which method is faster.
freematrix(matrixa, nrow, mcol); // free memory
freematrix(matrixb, nrwo, mcol); // free memory


I want to find another way to copy the data from a => b without loop all
the data.

See above. HTH

V
 
I

Ian McCulloch

Yudan said:
I have a problem to copy (assign) a matrix to another matrix. Curreny, I
know copy the number using loops, while it will take some time, I wonder
if there have faster method. The following code explain my situation
detailed.

double ** matrixa, **matrixb;
int nrow = 10, mcol = 10;
matrixa = initmatrix(nrow, mcol); // allocate memory a
matrixb = initmatrix(nrow, mcol); // allocate memory b
// copy a => b
for (int i=0;i<nrow;i++)
for (int j=0;j<mcol;j++)
matrixb[j] = matrixa[j];
freematrix(matrixa, nrow, mcol); // free memory
freematrix(matrixb, nrwo, mcol); // free memory


I want to find another way to copy the data from a => b without loop all
the data.

Thanks


For matrices, you are better off by far using a single array and addressing
it as matrix[ncols * i + j]. You get better data locality in the cache,
and you don't need a loop of malloc/new every time you want to make a copy.
With modern compilers & processors, the cost of the multiply is usually
either optimized away completely or irrelevant (a multiply is a cycle or
so, a memory lookup is at least a few, more likely a few dozen, cycles).
If you use something like BLAS (http://www.netlib.org/blas) to do the
underlying arithmetic, then even this cost disappears. Versus using nested
arrays requires an additional indirection which may be quite expensive.

Try wrapping this in a class as well, eg

class Matrix
{
public:
Matrix() : nrows_(0), ncols_(0), Data_(0) {}

Matrix(int nrows, int ncols) : nrows_(nrows), ncols_(ncols),
Data_(new double[nrows_ * ncols_]) {}

Matrix(Matrix const& Other) // fill in boring details
Matrix& operator=(Matrix const& Other); // fill in boring details

~Matrix() { delete[] Data_; }

double operator()(int i, int j) { return Data_[i * ncols + j]; }

// plus some functions to get the size, etc

private:
int nrows_, ncols_;
double* Data_;
};

With a bit of thought, you can do operator[] too, so you can use the 'old'
notation. Hint: return a pointer to the start of the row of the matrix.
But the operator() solution is easier, especially becuase it is trivial to
add some debug assert() statements to get bounds checking. That can
potentially save you an unbelievable amount of time, as can wrapping all of
the ugly memory management stuff inside a class.

By the way, for builtin types like double, you can use memcpy() to implement
the copy constructor and copy-assignment. Another advantage of the
single-array approach: you only need a single memcpy, versus a loop of them
for the multi-array approach. But don't do this for arrays of user-defined
types!

HTH,
Ian McCulloch
 
G

Gianni Mariani

Yudan said:
I have a problem to copy (assign) a matrix to another matrix. Curreny, I
know copy the number using loops, while it will take some time, I wonder if
there have faster method. The following code explain my situation detailed.

double ** matrixa, **matrixb;
int nrow = 10, mcol = 10;
matrixa = initmatrix(nrow, mcol); // allocate memory a
matrixb = initmatrix(nrow, mcol); // allocate memory b
// copy a => b
for (int i=0;i<nrow;i++)
for (int j=0;j<mcol;j++)
matrixb[j] = matrixa[j];
freematrix(matrixa, nrow, mcol); // free memory
freematrix(matrixb, nrwo, mcol); // free memory


I want to find another way to copy the data from a => b without loop all the
data.

Thanks


Use a matrix class ... (I posted the one below about a year ago)

#include <vector>

template <typename w_elem_type>
class matrix
{
public:
typedef int t_Size;

t_Size m_columns;
t_Size m_rows;

std::vector<w_elem_type> m_data;

matrix( t_Size i_columns = 0, t_Size i_rows = 0 )
: m_columns( i_columns ),
m_rows( i_rows ),
m_data( i_columns * i_rows )
{
}

w_elem_type * operator[]( t_Size i_index )
{
return & ( m_data[ i_index * m_rows ] );
}

template <typename w_Type, int w_columns, int w_rows>
matrix( const w_Type (&i_array)[w_columns][w_rows] )
: m_columns( w_columns ),
m_rows( w_rows ),
m_data( & (i_array[0][0]), & (i_array[w_columns-1][w_rows]) )
{
}

};

#include <iostream>

double array[3][4] = {
{ 1.0, 2.0, 3.3, 4.4 },
{ 1.0, 2.0, 3.3, 4.4 },
{ 1.0, 2.0, 3.3, 4.5 },

};

int main()
{
matrix<float> mat1( 3, 4 );
matrix<float> mat2;
matrix<float> mat3( array );

mat2 = mat3;

std::cout << mat2[2][3] << "\n";
}
 
E

E. Robert Tisdale

Yudan said:
I have a problem to copy (assign) a matrix to another matrix. Curreny, I
know copy the number using loops, while it will take some time, I wonder if
there have faster method. The following code explain my situation detailed.

double ** matrixa, **matrixb;
int nrow = 10, mcol = 10;
matrixa = initmatrix(nrow, mcol); // allocate memory a
matrixb = initmatrix(nrow, mcol); // allocate memory b
// copy a => b
for (int i=0;i<nrow;i++)
for (int j=0;j<mcol;j++)
matrixb[j] = matrixa[j];
freematrix(matrixa, nrow, mcol); // free memory
freematrix(matrixb, nrwo, mcol); // free memory


I want to find another way to copy the data from a => b without loop all the
data.


Take a look at
The C++ Scalar, Vector, Matrix and Tensor class Library

http://www.netwood.net/~edwin/svmtl/

The Object Oriented Numerics Page

http://www.oonumerics.org/oon/

and Bjarne Stroustrup, "The C++ Programming Language: Third Edition",
Chapter 22 Numerics, Section 4 Vector Arithmetic,
Subsection 6 Slice_array, pages 671-5
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,270
Messages
2,571,353
Members
48,041
Latest member
Oliwen826

Latest Threads

Top