How to multiply multiple matrices with C++ - c++

I'm doing a homework assignment which involves multiplying more than 2 matrices.
I thought about multiplying the first 2 matrices then take its result, continue multiplying it with the 3rd matrix, and repeat the same process until I multiply all the matrices together.
A * B * C = (A * B) * C = A * (B * C)
And here is my code so far. All of my matrices are stored in a 3D array of matrix[1][row][column].
// Calculate the result of first 2 matrices
for (int a = 0; a < n7; a++) {
for (int b = 0; b < n7; b++) {
for (int l = 0; l < n7; l++) {
sum += matrix[1][l][b] * matrix[0][a][l];
}
resultMatrix[a][b] = sum;
sum = 0;
}
}
// Check if k > 2, if yes then continue taking matrix[2] multiply with the result
if (k > 2) {
// Calculate to a tempResult matrix
for (int f = 2; f < k; f++) {
for (int a = 0; a < n7; a++) {
for (int b = 0; b < n7; b++) {
for (int l = 0; l < n7; l++) {
sum += matrix[f][l][b] * resultMatrix[a][l];
}
resultMatrix[a][b] = sum;
sum = 0;
}
}
// Pass the result to the original resultMatrix
for (int a = 0; a < n7; a++) {
for (int b = 0; b < n7; b++) {
resultMatrix[a][b] = tempResult[a][b];
}
}
}
}
I could not get the same result with an online matrix calculator and some manual input.
Please point out my mistakes, thank you!

Here is one solution.. Although I didn't applied dimension check of the matrices. So if you multiply a (3X4) & (2X4) matrix, it will not warn you. It can be done very easily with very simple steps. It worked for me with
A = 1 2 3 4
5 6 7 8 [4X4]
0 1 2 3
7 8 9 0
B = 2 3 4
5 6 7 [4X3]
8 9 0
3 4 5
c = 1
2 [3X1]
3
D = 1 1 -2 -1 [1X4]
Result = 278 278 556 -278
718 718 1436 -718 [4X4]
168 168 336 -168
678 678 1356 -678
The program:
#include <iostream>
#include <iomanip>
void displaymat(double* p, int r, int c)
{
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
std::cout << std::setw(15) << *(p + i * c + j) << "\t";
}
std::cout << std::endl;
}
std::cout << "\n\n" << std::endl;
}
void matrix_multiply(double** a, double* b, int* rf, int* cf, int num)
{
double sum;
double** interim_result = new double* [num - 1]{nullptr};
for (int i = 0; i < num - 1; i++)
{
interim_result[i] = new double[rf[0] * cf[i + 1]]{ 0 };
}
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < rf[0]; j++)
{
for (int k = 0; k < cf[i + 1]; k++)
{
sum = 0;
for (int l = 0; l < cf[i]; l++)
{
if (i == 0)
{
sum = sum + a[i][cf[i] * j + l] * a[i + 1][cf[i + 1] * l + k];
}
else
{
sum = sum + interim_result[i - 1][cf[i] * j + l] * a[i + 1][cf[i + 1] * l + k];
}
}
interim_result[i][j * cf[i + 1] + k] = sum;
}
}
//displaymat(interim_result[i], rf[0], cf[i + 1]);
}
for (int i = 0; i < rf[0] * cf[num - 1]; i++)
{
b[i] = interim_result[num - 2][i];
}
for (int i = 0; i < num - 1; i++)
{
delete[] interim_result[i];
}
delete[] interim_result;
}
int main()
{
int num; // total number of matrices
char ch = 'a';
std::cout << "How many matrices/matrix?:";
std::cin >> num;
std::cout << std::endl;
double** mat = new double* [num]; // double pointer for stacks of matrices
int* r = new int[num]{0}; // to store the rows the matrices
int* c = new int[num]{0}; // to store the columns of matrices
for (int n = 0; n < num; n++)
{
std::cout << "matrix:" << n + 1 << "\n" << std::endl;
std::cout << "rows:";
std::cin >> r[n]; // input
std::cout << "columns:";
std::cin >> c[n]; // input
std::cout << std::endl;
mat[n] = new double[(r[n] * c[n])]; // for getting elements
for (int i = 0; i < c[n] * r[n]; i++)
{
std::cout << ch << "[" << i / c[n] + 1 << "][" << i % c[n] + 1 << "]:";//ch << "[" << i / c[n] << "]" << "[" << i % c[n] << "]:";
std::cin >> *(*(mat + n) + i);
}
displaymat(mat[n], r[n], c[n]);
ch++;
}
double* result = new double[r[0] * c[num - 1]];
matrix_multiply(mat, result, r, c, num);
std::cout << "Result=" << std::endl;
displaymat(result, r[0], c[num - 1]);
for (int i = 0; i < num; i++)
{
delete[] * (mat + i);
}
delete[] mat;
delete[] result;
delete[] r;
delete[] c;
}

Related

Count the determinant. Subtract from each element of the main diagonal X

My program counts the determinant of a matrix.
square matrix size = 3
source
the matrix
1 2 3
4 5 6 -> и вычесть из каждого элемента главной диагонали X
7 8 9
1-x 2 3
4 5-x 6 ->решить определитель
7 8 9-x
#include<iostream>
#include<math.h>
using namespace std;
int determinant(int matrix[10][10], int n) {
int det = 0;
int submatrix[10][10];
if (n == 2)
return ((matrix[0][0] * matrix[1][1]) - (matrix[1][0] * matrix[0][1]));
else {
for (int x = 0; x < n; x++) {
int subi = 0;
for (int i = 1; i < n; i++) {
int subj = 0;
for (int j = 0; j < n; j++) {
if (j == x)
continue;
submatrix[subi][subj] = matrix[i][j];
subj++;
}
subi++;
}
det = det + (pow(-1, x) * matrix[0][x] * determinant(submatrix, n - 1));
}
}
return det;
}
int main() {
int n, i, j,x;
int matrix[10][10];
cout << "Enter the size of the matrix:\n";
cin >> n;
cout << "Enter the elements of the matrix:\n";
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
cin >> matrix[i][j];
cout << "The entered matrix is:" << endl;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
cout << matrix[i][j] << " ";
cout << endl;
}
cout << "Determinant of the matrix is " << determinant(matrix, n);
return 0;
}

having trouble making a function to find the determinant of a matrix

Probably a simple fix, but I keep getting 0 as the determinate when I should be getting 22, I have to use dynamic memory allocation as well. Might be some problem with using floats as I am not completely familiar with how they work with pointers. Honestly don't know what could be causing the function to output a zero.
cpp.sh link to test: http://cpp.sh/5bu2v
#include <iostream>
#include <math.h>
using namespace std;
float determinant(float *mat1, int &rows1)
{
float s = 1, D = 0;
float *temp = new float[rows1 * rows1];
int i, j, m, n, c;
if (rows1 == 1)
{
return (*(mat1 + 0 * rows1 + 0));
}
else
{
D = 0;
for (c = 0; c < rows1; c++)
{
m = 0;
n = 0;
for (i = 0; i < rows1; i++)
{
for (j = 0; j < rows1; j++)
{
*(temp + i * rows1 + j) = 0;
if (i != 0 && j != c)
{
*(temp + m * rows1 + n) = *(mat1 + i * rows1 + j);
if (n < (rows1 - 2))
n++;
else
{
n = 0;
m++;
}
}
}
}
int V1 = rows1 - 1;
D = D + s * (*(mat1 + 0 * rows1 + c) * determinant(temp, V1));
s = -1 * s;
}
}
return (D);
}
int main()
{
int i, j;
int n = 3;
int matrix[10][10] = {{1, 2, 3},
{0, 4, 5},
{1, 0, 6}};
float *mat1 = new float[n * n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
*(mat1 + i * n + j) = matrix[i][j];
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
cout << matrix[i][j] << " ";
cout << endl;
}
cout << "Determinant of the matrix is " << determinant(mat1, n);
return 0;
}
Your first call into determinant, mat is a 3x3 matrix stored in a 1 dimensional array. Visualize it like this:
A B C
D E F
G H I
You create another 3x3 matrix, temp.
You series of loops to fill the temp matrix exclude the first row and column c, so it ends up looking like this the first time thru:
D E 0
G H 0
0 0 0
This gets passed to determinant, which is expecting a 2x2 matrix. Since you've passed it something else, what the recursive call sees is
D E
0 G
When you construct temp you need to do it with the smaller matrix size, not the source size.

dynamically allocating memory to matrices

I am trying to convert an array to a matrix, so I dynamically allocated memory to the matrix, but I'm getting an error:
CRT detected that the application wrote to memory after end of heap buffer
int main() {
float a[9] = { 1, 3, 5, 6,4,6,5,6,8};
int b = sizeof(a)/sizeof(a[0]);
int r = sqrt(b) - 1;
float **A_mat = new float*[r];
//A_mat = ;
for (int i = 0; i <= r; i++)
A_mat[i] = new float[r];
for (int j = 0; j <= r; j++) {
for (int i = 0; i <= r; i++) {
A_mat[j][i] = a[i + j * (r+1)];
}
}
cout << "a[0,0] is " << A_mat[0][0] << endl;
cout << "a[0,2] is " << A_mat[0][2] << endl;
cout << "a[1,0] is " << A_mat[1][0] << endl;
cout << "a[2,0] is " << A_mat[2][0] << endl;
for (int i = 0; i <= r; i++) {
delete[] A_mat[i];
}
delete[] A_mat;
system("pause");
}
Your code has two major issues:
Issue 1:
float **A_mat = new float*[r]; // allocating memory for 2 rows because r = sqrt(9) - 1 => r = 2
for (int i = 0; i <= r; i++)
A_mat[i] = new float[r]; // Usage of A_mat[r] for r = 2 is out of bounds. Also, memory is allocated for 2 columns.
Issue 2:
for (int j = 0; j <= r; j++) {
for (int i = 0; i <= r; i++) {
A_mat[j][i] = a[i + j * (r+1)]; // accessing indices (0, 2), (1, 2), (2, 0), (2, 1), (2, 2) are out of bounds
}
}
Instead, you should allocate (r + 1) size memory. Like this:
int main() {
float a[9] = { 1, 3, 5, 6,4,6,5,6,8};
int b = sizeof(a)/sizeof(a[0]);
int r = sqrt(b) - 1;
float **A_mat = new float*[r + 1];
//A_mat = ;
for (int i = 0; i <= r; i++)
A_mat[i] = new float[r + 1];
for (int j = 0; j <= r; j++) {
for (int i = 0; i <= r; i++) {
A_mat[j][i] = a[i + j * (r+1)];
}
}
cout << "a[0,0] is " << A_mat[0][0] << endl;
cout << "a[0,2] is " << A_mat[0][2] << endl;
cout << "a[1,0] is " << A_mat[1][0] << endl;
cout << "a[2,0] is " << A_mat[2][0] << endl;
for (int i = 0; i <= r; i++) {
delete[] A_mat[i];
}
delete[] A_mat;
system("pause");
}
Suggestions:
1) Never use raw pointers. Always look for safer alternatives. In this case, you should go for std::vector.
2) Never use naked new. It is generally the major source of Memory leaks. Though currently, its not the case for you. But it might become an issue in the future.
3) Always remember that array starts from 0-indexing in C++.
You have problem with for loop. The index is from 0 to (r-1). But your for loop from 0 to r. It made out of bound of your array.
1> So please replace this for loop
for (int i = 0; i <= r; i++)
by
for (int i = 0; i < r; i++)
2> And replace this statements
for (int j = 0; j <= r; j++) {
for (int i = 0; i <= r; i++) {
A_mat[j][i] = a[i + j * (r+1)];
}
}
by
for (int j = 0; j < r; j++) {
for (int i = 0; i < r; i++) {
A_mat[j][i] = a[i + j * r];
}
}

Output not correct for my C++ program

So, I have the following problem:
From the file tabl.in a number n will be read (n<=50).
After that a square array with n rows and n columns will be read; all the numbers in the array will be composed by a maximum of 2 digits each.
Shown in the file tabl.out, the modulo between the sum of numbers found on the second diagonal of the array and 10, if the sum is palindrome (true=1, false=0), and the arithmetic mean of elements situated below of the main diagonal.
Will be writing functions for:
reading the array
calculation of the operation sum of secondary diagonal%10
checking if the previous result it is palindrome
calculation of the arithmetic mean below main diagonal
Example:
tabl.in:
4
5 8 2 12
1 0 3 16
1 2 1 11
5 7 2 19
tabl.out:
2 1 3
where
(12+3+2+5)%10 = 22%10 = 2
22 is palindrome = 1
1+2+2+1+7+5 = 18, 18/6=3
My code so far is:
#include <fstream>
using namespace std;
ifstream fin("tabl.in");
ofstream fout("tabl.out");
void readn(int Arr[][51], int n) {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
fin >> Arr[i][j];
}
int sumsec(int Arr[][51], int n) {
int s = 0;
float r;
for (int i = 1; i <= n; i++)
s = s + Arr[i][n - i + 1];
r = s % 10;
return r;
}
void pald(int Arr[][51], int n) {
int s = 0, pal = 0;
for (int i = 1; i < n; i++)
s = s + Arr[i][n - i + 1];
while (s != 0) {
pal = pal * 10 + s % 10;
s = s / 10;
}
if (pal == s)
fout << "1 ";
else
fout << "0 ";
}
int ambmd(int Arr[][51], int n) {
int s = 0, k;
float ame;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i - 1; j++) {
s = s + Arr[i][j];
k++;
}
}
ame = s / k;
return ame;
}
int main() {
int Arr[51][51], n;
float r, ame;
fin >> n;
readn(Arr, n);
r = sumsec(Arr, n);
fout << r << " ";
pald(Arr, n);
ame = ambmd(Arr, n);
fout << ame;
}
But I have an issue with the palindrome() function: my output file will have 2 0 3 written to it for the given array from the example, instead of 2 1 3. What am I doing wrong?
Your pald function would work, if you compute s the same way as you do in sumsec and if s would still contain the sum, after you compute pal.
In your case, while (s != 0) {...}, followed by if (pal == s) {...} could be re-written as if (pal == 0), which is clearly not the intended solution. Just save your sum before computing pal, then compare with the saved sum.
Also, change your loop condition for computing s to for (int i = 1; i <= n; i++).
int s = 0, pal = 0, sum = 0;
for (int i = 1; i <= n; i++)
s = s + Arr[i][n - i + 1];
sum = s;
while (s != 0) {
pal = pal * 10 + s % 10;
s = s / 10;
}
if (pal == sum)
fout << "1 ";
else
fout << "0 ";
You should also consider the various comments for code improvements, like not re-computing the sum in the pald function.

Run-Time Check Failure #2 - Stack around the variable 'B' was corrupted

this error keeps coming up yet i dont see a problem with the code (its in c++)
the program is supposed to find the inverse of a 2x2 matrix
#include <iostream>
using namespace std;
int main() {
float d;
float A[2][2], B[2][2];
do {
cout << "please enter valid parameters in for 11,12,21,22" << endl;
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++)
cin >> A[i][j];
}
d = (A[1][1] * A[2][2]) - (A[1][2] * A[2][1]);
} while(d == 0);
B[1][1] = A[2][2] * (1.0 / d);
B[1][2] = A[1][2] * (-1.0 / d);
B[2][1] = A[2][1] * (-1.0 / d);
B[2][2] = A[1][1] * (1.0 / d);
for(int k = 0; k < 2; k++) {
for(int h = 0; h < 2; h++)
cout << B[k][h] << " ";
cout << endl;
}
return 0;
}
You are indexing B and A from 1 to 2 , instead use it from 0 to 1.