Sign in to follow this  
serious_learner07

Single matrix multiplication Function

Recommended Posts

In my application, I have three matrix multiplication. (1) Between 15 x 10 and 10 x 13 matrix. (2) Between 1 x 10(row matrix) and 10 x10 matrix. (3) Between 1x10(row matrix) and 10 x 1(column matrix) matrix For this I want to write single Function like this.
void matrixmultiply(float** array1, float ** array2, float ** array3, int array1_row_count,int array1_column_count,int array2_column_count)
{				
	int i,j,k;
	for( i=0; i<array1_row_count; i++)
	{
		for( j=0; j< array2_column_count; j++)
		{
			array3[i][j] = 0;
			for( k = 0; k<array1_column_count; k++)
			{
				array3[i][j]  += array1[i][k] * array2[k][j];
				printf("%f\n",array3[i][j]);
			}
		}
	}
}
For (2) and (3) first parameter happen to be float*,(since 1x10 array) and second parameter in the case of (3) is also float*(since 10x1 array). How can I write a single Function with all array parameters being float**. I want my function to pass by pointer(not by array). Thanks in advance

Share this post


Link to post
Share on other sites
your NxM matrix should not be a float **. for performance, you'd be better off with just a float *.

float *matrix = new float[N*M]; (or = (float*)malloc(sizeof(float)*N*M) since it looks like you are doing C not C++ )
with element [i][j] accessed as matrix[i*M+j]
so the multiplication could be written as:

matrixOut[i*array2_column_count+j] += matrixIn1[i*array1_column_count+k] * matrixIn2[k*array2_column_count+j];

Share this post


Link to post
Share on other sites
(1) Obligatory warning-type question: Are you actually writing in C, or are you simply not aware of the huge range or more sophisticated C++ tools for this kind of thing?

(2) Assuming C: At least use some kind of data structure, to bind the memory together with size information.

(3) As needed, a matrix's memory allocation only needs to be a single (element type)*, not a **. The type doesn't depend on the width and height, and there isn't a real way to optimize on that basis, anyway (not without huge amounts of extra work, at least). But you can still pack all the data into a single linear chunk, for the reason that your grid is rectangular. You can look at a line of data and make each element correspond to a row and column, because you know the lengths of the rows. (This is, after all, how memory works. Pointers are, conceptually, single numbers, not pairs of numbers.)

Assuming C:


typedef struct matrix_t {
int rows, columns;
float* data;
} matrix;

void init_matrix(matrix* m, int rows, int columns) {
int i;

m->data = malloc(sizeof(float) * rows * columns);
m->rows = m->data ? rows : -1;
m->columns = m->data ? columns : -1;

if (m_data) {
for (i = 0; i < rows * columns; ++i) {
m->data[i] = 0;
}
}
}

void clean_matrix(matrix* m) {
if (m->data) { free(m->data); }
m->data = NULL; m->rows = -1; m->columns = -1;
}

void set_matrix(matrix* m, int rows, int columns) {
if (m->data) { free(m->data); }
init_matrix(m, rows, columns);
}

float get(matrix* m, int x, int y) {
assert x >= 0 && x < m->rows && y >= 0 && y < m->columns;
return m->data[y * m->rows + x];
}

float set(matrix* m, int x, int y, float value) {
assert x >= 0 && x < m->rows && y >= 0 && y < m->columns;
m->data[y * m->rows + x] = value;
}

int multiply(matrix* x, matrix* y, matrix* result) {
int i, j, k;
if (x->columns != y->rows) { return 0; }

set_matrix(result, x->rows, y->columns);
for (i = 0; i < x->rows; ++i) {
for (j = 0; j < y->columns; ++j) {
for (k = 0; k < x->columns; k++) {
set(result, i, j, get(result, i, j) + get(x, i, k) * get(y, k, j));
}
}
}
}



Quote:
I want my function to pass by pointer(not by array).


Here's the thing: there is no such thing as "passing by array". When you write a function signature like "int wibble(char x[42])", the compiler ignores the number 42, and treats it just as if you had written "int wibble(char* x)". Sorry to say. (With multidimensional arrays, this becomes more complicated, but to pass a multidimensional array around in C, you either need to "flatten" it, or specify the size of all but one dimension ahead of time.)

Share this post


Link to post
Share on other sites
Quote:

"int wibble(char x[42])", the compiler ignores the number 42,


Doesn't it keep that around at least at compile time to give you the wonderful error:
char n[20];
wibble ( n ); << can't convert char[20] to char[42]

or am i thinking of a different function signature that gives that type of error.

Share this post


Link to post
Share on other sites
Nope. According to section 13.1 paragraph 3 of the C++ Standard, int wibble(char x[42]), int wibble(char x[20]) and int wibble(char * x) are all the same thing.

Share this post


Link to post
Share on other sites
Not in C++. If you don't believe the language standard, then try entering:

int wibble(char (x[42]));

int main(int, char **) {
char fuzz[30];
wibble(fuzz);
}

into a compiler. Every version of MSVC and g++ I have on my computer accept it without a single complaint.

Share this post


Link to post
Share on other sites
Quote:
Original post by KulSeran
Quote:

"int wibble(char x[42])", the compiler ignores the number 42,


Doesn't it keep that around at least at compile time to give you the wonderful error:
char n[20];
wibble ( n ); << can't convert char[20] to char[42]

or am i thinking of a different function signature that gives that type of error.


You are probably thinking of the fact that the compiler remembers the lengths of string literals, and mentions them when reporting certain kinds of const-correctness problems.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kenneth Gorking
To make sure that a function only accepts arrays of certain sizes, you can use 'int wibble(char (x[42]))'.

No. You were probably thinking of int wibble(char (&x)[42]), but since references only exist in C++, you should use better C++ abstractions than that.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this