Welcome to the Parallax Discussion Forums, sign-up to participate.

# Matrix Multiplication

Posts: 43
Hello,

I am trying to find an example of how to multiply two matrices (for example, two 3x3 matrices) in C. Does anyone know of any tutorials online that explain this? I know I have to use pointers but I'm having a hard time grasping how to do this task.

Thanks,
David

• Posts: 1,929
edited April 2017
This is the simplest (loop based, in C) form:
```void simple_mul(const float a[3][3], const float b[3][3], float out[3][3]) {
int i,j,m,n;
for(i=0;i<3;i++) {  // for each output row
for(j=0;j<3;j++) {  // for each output column
out[i][j] = 0.0f;  // zero the value being computed
for(m=0;m<3;m++) {
out[i][j] += a[i][m]*b[m][j];  // accumulate the row & column multiplies
}
}
}
}
```
Expanded out, it looks more like this:
```   void mult(const Matrix3D & a, const Matrix3D & b, Matrix3D & out)
{
out.M11 = a.M11 * b.M11 + a.M12 * b.M21 + a.M13 * b.M31;
out.M12 = a.M11 * b.M12 + a.M12 * b.M22 + a.M13 * b.M32;
out.M13 = a.M11 * b.M13 + a.M12 * b.M23 + a.M13 * b.M33;
out.M21 = a.M21 * b.M11 + a.M22 * b.M21 + a.M23 * b.M31;
out.M22 = a.M21 * b.M12 + a.M22 * b.M22 + a.M23 * b.M32;
out.M23 = a.M21 * b.M13 + a.M22 * b.M23 + a.M23 * b.M33;
out.M31 = a.M31 * b.M11 + a.M32 * b.M21 + a.M33 * b.M31;
out.M32 = a.M31 * b.M12 + a.M32 * b.M22 + a.M33 * b.M32;
out.M33 = a.M31 * b.M13 + a.M32 * b.M23 + a.M33 * b.M33;
}
```
• Posts: 20,215
I would forget about using pointers. Just use two dimensional arrays. Work through the multiplication in the same way you did in high school. There are examples all over the net. For example this one:

https://codeitaway.wordpress.com/2012/01/26/c-program-to-multiply-two-matrix-multiplication-of-3x3-matrix-in-c/

• Posts: 2,455
edited April 2017
I've not run it but I think this would work.
```for (int i=0;i<3;i++) {
for (int j=0;j<3;j++) {
for (int k=0;k<3;k++) {
resultMatrix[i][j] += firstMatrix[i][k]*secondMatrix[j][k];
}
}
}
```

Each element in the product of matrices is the sum of the products of the row and corresponding column, so this produce the output of the sum of 2 3x3 matrices. Not very efficient with 3 nested loops, though.
Projects, tutorials, and more! http://microcontrolled.com/
• Posts: 43
All,

Thank you for your replies. Apologies for getting back so late - been busy. Below is a piece of code I was working on when I posted my original question. It looks like I had something similar to your responses in terms of the algorithm. I think my main problem is passing matrices to a function - a matrix multiply function in this case. Do you have to use pointers to pass arrays to functions, and if so, how can I do this?
```/*
Matrix Multiplication with Floats.c
Output in matrix form.
*/

#include "simpletools.h" // Include simple tools

float p[3][3] = {
{0.173, 1, 2},
{3, 4, 5},
{6, 7, 8.632}
};

float q[3][3] = {
{0, 1, 2},
{3, 4, 5},
{6, 7, 8}
};

int main() // Main function
{
matrixMultiply(p, q);
}

matrixMultiply() // 3x3 matrixMultiply function
{
for(int i = 0; i < 3; i++)
{
for(int k = 0; k < 3; k++)
{
float sum = 0;
for(int j = 0; j < 3; j++)
{
sum = sum + p[i][j] * q[j][k];
if(j == 2)
{
print("%f ", sum);
if (k==2)
{
print("\n");
}
}
}
}
```

Respectfully,
David
• Posts: 8,397
This may be a prime example of why many scientist like Fortran and engineers Matlab... This kind of thing is built into both...

But, they have a lot of baggage would wouldn't fit in a microcontroller...
Prop Info and Apps: http://www.rayslogic.com/
• Posts: 20,215
```void matrixMultiply(float p[3][3], float q[3][3], float r[3][3])
{
for (int i=0;i<3;i++) {
for (int j=0;j<3;j++) {
for (int k=0;k<3;k++) {
r[i][j] += p[i][k] * q[j][k];
}
}
}
}
[code]

and call it as you have done:
[code]
float p[3][3] = {.....};    // First matrix
float q[3][3] = {.....};    // Second matrix
float r[3][3] = {.....};     // Result matrix

matrixMultiply(p, q, r);
```

In C the name of an array is actually a pointer, so for

int a[10];

"a" is a pointer to int. int *.

• Posts: 1,929
Heater is correct. It's also possible to define the matrix as an array of [9] elements, instead of an array of [3][3] elements, and deal with the row/column addressing yourself, but that's a pain. I'm not suggesting you do that, but if you're looking at other people's code you might see that approach - it's pretty common.
• Posts: 43
All,

Thank you so much for your help. I was able to get it working :) Microcontrolled mentioned that this approach is not efficient with 3 nested loops. Is there a "better" or more efficient way to do this? I may have some other questions as I work through some other matrix math functions. Thanks again! Here is the working code:
```/* Multiply two 3 by 3 matrices */
#include "simpletools.h"

float p[3][3] = {       // Define matrix p
{0, 1, 2},
{3, 4, 5},
{6, 7, 8}
};

float q[3][3] = {       // Define matrix q
{0, 1, 2},
{3, 4, 5},
{6, 7, 8}
};

float r[3][3] = {       // Zero matrix r
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}
};

float matrixMultiply(float p[3][3], float q[3][3], float r[3][3]);        // Declare matrixMultiply function

int main(){

matrixMultiply(p, q, r);        // Call matrixMultiply function

// Print matrix r
print("r =\n");
for(int i = 0; i < 3; i++){
for(int k = 0; k < 3; k++){
print("%f ", r[i][k]);
}
print("\n");
}
}

// matrixMultiply function - compute a 3 by 3 matrix
float matrixMultiply(float p[3][3], float q[3][3], float r[3][3]){
for(int i = 0; i < 3; i++){
for(int k = 0; k < 3; k++){
for(int j = 0; j < 3; j++){
r[i][k] = r[i][k] + p[i][j] * q[j][k];
}
}
}
}
```

Respectfully,
David
• Posts: 20,215
edited May 2017
Well done.

I'm sure you can imagine that the line:
```    r[i][k] = r[i][k] + p[i][j] * q[j][k];
```

is executed 3 * 3 * 3 = 27 times as all those loops go around.

On each execution i, j, k have some value between 0 and 2.

So one optimization would be to get rid of all the loops and write out that line 27 times with the correct numbers instead of i, j and k.

That would get rid of all the instructions that do the loop jumping, incrementing and testing of i, j and k. It would just run through a straight line of 27 statements that are actually doing the work you want.

This kind of optimization is known as "loop unrolling".
• Posts: 1,929
If you look at my first response, the function "simple_mul" is using nested loops, where the second version called "mult" is unrolled and written with no loops. The unrolled version is faster since the computer doesn't have to keep track of all the loop variables or dynamically figure out which matrix values you're working with for each iteration - that's all hard coded in the second version so you can just rip through the math.

That said, when loops are simple enough, modern compilers will do a lot of loop unrolling for you, so you might not see much gain (in an optimized build, at least).
• Posts: 43
Heater and Jason,

Thank you for your detailed responses. This forum is great for someone like me.

Respectfully,
David
• Posts: 1,132
This forum is great for someone like me.

David, I'm sure I speak for many of us that it's a great place for us too !
- Howard
• Posts: 20,215
This forum is a great place for everyone here. Novice to guru, everyone has questions about something sometime. It's give and take all around.
• Posts: 1,929
One of the reasons I like it here is because I learn a lot about hardware. I've been a software dev for a long time, so I can contribute that way, but for hardware I'm usually in over my head. :) It's nice to be able to contribute back to the community that I learned so much from.