Why is my matrix multiplication code not working? - c++

I am new to C++ and I have written a C++ OpenMp Matrix Multiplication code that multiplies two 1000x1000 matrices. So far its not running and I am having a hard time finding out where the bugs are. I tried to figure it out for a few days but I'm stuck.
Here is my code:
#include <iostream>
#include <time.h>
#include <omp.h>
using namespace std;
int N;
void Multiply()
{
//initialize matrices with random numbers
//#pragma omp for
int aMatrix[N][N], i, j;
for( i = 0; i < N; ++i)
{for( j = 0; j < N; ++j)
{aMatrix[i][j] = rand();}
}
int bMatrix[N][N], i1, j2;
for( i1 = 0; i1 < N; ++i1)
{for( j2 = 0; j2 < N; ++j2)
{bMatrix[i1][j2] = rand();}
}
//Result Matrix
int product[N][N] = {0};
//Transpose Matrix;
int BTransposed[j][i];
BTransposed[j][i] = bMatrix[i1][j2];
for (int row = 0; row < N; row++) {
for (int col = 0; col < N; col++) {
// Multiply the row of A by the column of B to get the row, column of product.
for (int inner = 0; inner < N; inner++) {
product[row][col] += aMatrix[row][inner] * BTransposed[col][inner];
}
}
}
}
int main() {
time_t begin, end;
time(&begin);
Multiply();
time(&end);
time_t elapsed = end - begin;
cout << ("Time measured: ") << endl;
cout << elapsed << endl;
return 0;
}```

The transposed matrix (BTransposed) is not correctly constructed. You can solve this in the following ways:
First Option: use a for loop to create the correct BTransposed matrix.
for (int i = 0; i != N; i++)
for (int j = 0; j != N; j++)
BTransposed[i][j] = bMatrix[j][i]
Second Option (better one): completely delete BTransposed matrix. when needed just use the original bMatrix with indexes i,j exchanged! for example instead of BTransposed[col][inner] you can use BMatrix[inner][col].

You created a matrix
int BTransposed[j][i];
BTransposed[j][i] = bMatrix[i1][j2];
that has the size j x i and than u make the element at [j][i] equal to the element in bMatrix[i1][j2], you should have an error since u cant accses the index j and i since it goes from 0 to j-1 and i-1

Related

check duplicate numbers with bool function in matrix c++

I created a matrix[10][10] with random numbers
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
matrix[i][j] = rand() % 100 ;
}
}
But I need to use bool function for check duplicate numbers and if its same use random again.How can i do it?
An efficient way to test for duplicates is to store the elements that have been inserted into the matrix in a std::vector and to use to std::find. This allows to check whether a newly generated random number is already included in the previously stored elements or not. If it is found, then another random number should be generated and the test repeated.
#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>
bool alreadySelected(int n, int nvalues, int values[][10]) {
std::vector<int> v(&values[0][0], &values[0][0] + nvalues );
return (std::find(v.begin(), v.end(), n) != v.end());
}
int main() {
int matrix[10][10];
for (int i = 0; i < 10; i++) {
int n;
bool dupe;
for (int j = 0; j < 10; j++) {
int nvalues = i * 10 + j;
do {
n = std::rand() % 100 ;
dupe = alreadySelected( n, nvalues, matrix );
} while ( dupe );
matrix[i][j] = n;
std::cout << matrix[i][j] << " ";
}
std::cout << "\n";
}
}
A much simpler way to generate such a matrix would be to use std::random_shuffle.
There are multiple ways to achieve this.
Write a function which returns bool and takes 10*10 matrix size. Compute sum of all numbers. Compare this result with the sum of numbers from 1...99. If both matches then no duplicate return true, otherwise duplicate return false. Sum of 1..99 can be calculated using n(n+1)/2, where n = 99.
In function create array of size 100. Initialize all array elements with 0. Iterate over matrix, use matrix element as index of array. If array contains 1 at that position you got duplicate element otherwise make array element at that index 0.
Implementation of first approach
#include <iostream>
#include <cstdlib>
#include <iomanip>
#define ROW 10
#define COL 10
#define MOD 100
int main()
{
int mat[ROW][COL];
int sum = 0;
int range_sum = ((MOD-1)*(MOD))/2; // n = MOD-1, sum = n(n+1)/2
while(true){
sum = 0;
for(int i = 0; i < ROW; i++){
for(int j = 0; j < COL; j++){
mat[i][j] = rand()%MOD;
sum += mat[i][j];
}
}
if(sum==range_sum){
break;
}
}
for(int i = 0; i < ROW; i++){
for(int j = 0; j < COL; j++){
std::cout << std::setw(2) << mat[i][j] << " ";
}
std::cout << std::endl;
}
return 0;
}

C++ 2D array and boost random number generator

I put in my program two loops - one fills 2D array with one value N0, and next loop is generating random number. And my program does not work when I have loop for array. I get "Unhandled exception... (parameters: 0x00000003)". But without first loop it works correctly. Thanks for help.
#include <iostream>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
using namespace std;
const double czas = 1E9;
int main()
{
//Declaration of variables
const int k = 20;
const int L = 30;
double N0 = 7.9E9;
int t,i,j, WalkerAmount;
double excitation, ExcitationAmount;
double slab[30][600];
//Random number generator
boost::random::mt19937 gen;
boost::random::uniform_int_distribution<> numberGenerator(1, 4);
//Filling slab with excitation
for (int i = 0; i <= L; i++)
{
for (int j = 0; j <= k*L; j++) { slab[i][j] = N0; }
}
//Time loop
for (t = 0; t < czas; t++) {
WalkerAmount = 0;
ExcitationAmount = 0;
for (int i = 0; i <= L; i++)
{
for (int j = 0; j <= k*L; j++)
{
int r = numberGenerator(gen);
cout << r << endl;
}
}
}
system("pause");
return 0;
}
Arrays in C++ are indexed from 0 to n-1 where n is the capacity of the array. Then, the code following code is wrong.
int main()
{
//Declaration of variables
const int k = 20;
const int L = 30;
double N0 = 7.9E9;
double slab[30][600];
// [...]
for (int i = 0; i <= L; i++)
{
for (int j = 0; j <= k*L; j++) { slab[i][j] = N0; }
}
}
When you initialize your array, you always go one steep too far. As you consider the case where i == L and j == k*L you reach an area in the memory that out of your array.
The loop you want to execute is
for (int i = 0; i < L; i++)
for (int j = 0; j < k*L; j++)
// Initialize

Memory hack to transpose matrix corrupts stack, C++

I need to implement a matrix transpose procedure in C++.
The problem is the signature, the function has to be called like this:
transpose(in_mat[0][0], n, m, out_mat[0][0])
where n and m are the dimensions.
All values are doubles, both the matrices and the dimensions.
Since the code is automatically generated, I can't fix this.
My workaround looks like this:
void transpose(double& in_mat, const double _n, const double _m, double& out_mat)
{
int n = _n, m = _m;
double* in_pointer= &in_mat;
double* out_pointer= &out_mat;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
*(out_pointer+(j*n+i)) = *(in_pointer+(i*m + j));
}
}
}
It works fine.
I've constructed a test case with two matrices of different width and height. One is filled with random numbers, the other is filled with zeros. Then the transpose procedure is called and the two matrices are compared.
The functionality is correct.
But it corrupts the stack. When run in Visual Studio 2015 there is a warning
Run-Time Check Failure #2 - Stack around the variable 'in_mat' was corrupted.
What did I do wrong ? Why is the stack corrupted ?
Code after the invocation of transpose works correctly.
EDIT:
Here is the complete setup:
#include <random>
#include <iostream>
void transpose(double& in_mat, const double _n, const double _m, double& out_mat)
{
int n = _n, m = _m;
double* in_pointer = &in_mat;
double* out_pointer = &out_mat;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
*(out_pointer+(j*n+i)) = *(in_pointer+(i*m + j));
}
}
}
int main()
{
double in_mat[5][4];
double out_mat[4][5];// assign matrix
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 5; j++) {
in_mat[i][j] = std::rand();
out_mat[j][i] = 0;
}
}
double n = 5;
double m = 4;
transpose(in_mat[0][0], n, m, out_mat[0][0]);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (in_mat[i][j] - out_mat[j][i]>0.0001) {
std::cout << "code is broken" << std::endl; //never reached
}
}
}
std::cout << "finished" << std::endl;
}
Your subscripts (or loop limits) were backwards where you initialized the matrices.
You have
double in_mat[5][4];
double out_mat[4][5];// assign matrix
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 5; j++) {
in_mat[i][j] = std::rand();
out_mat[j][i] = 0;
}
}
When j==4 you are writing beyond the end of out_mat

How can I properly add and access items to a multidimensional vector using loops?

I have this program that is trying to determine how many unique items are within some intersecting sets. The amount of input entirely depends on the the first value n, and then the amount of sets entered afterward. For example, if I start with entering n = 2, I am expected to enter 2 integers. The program then determines how many intersections there are between n items (this is like choosing 2 items from n items). This goes on as k increments. But that's kind of beyond the point. Just some background info.
My program adapts correctly and accepts the proper amount of input, but it stops working properly before the first for loop that is outside of the while loop. What I have tried to do is make a vector of integer vectors and then add every other row (when index starts at 0 AND index starts at 1). But I am guessing I have constructed my vectors incorrectly. Does anybody see an error in my vector logic?
#include <iostream>
#include <vector>
using namespace std;
int fact (int m) {
if (m <= 1)
return 1;
return m * fact(m - 1);
}
int comb (int n, int k) {
return fact(n)/(fact(n-k)*fact(k));
}
int main() {
int n = 0;
int k = 2;
int sum = 0;
int diff = 0;
int final = 0;
vector <vector <int> > arr;
cin >> n;
while (n > 0) {
vector <int> row;
int u;
for (int i = 0; i < n ; ++i) {
cin >> u;
row.push_back(u);
}
arr.push_back(row);
n = comb(row.size(), k);
k++;
}
for (int i = 0; i < arr.size(); i+2)
for (int j = 0; j < arr[i].size(); ++j)
sum += arr[i][j];
for (int i = 1; i < arr.size(); i+2)
for (int j = 0; j < arr[i].size(); ++j)
diff += arr[i][j];
final = sum - diff;
cout << final;
return 0;
}
for (int i = 0; i < arr.size(); i+=2)
^
You want to do i+=2 or i=i+2, else the value of i is never changed, leading to an infinite loop.

How to sort elements into C++ matrix?

I'm new to C++ programming. I need to sort this matrix:
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
int main(int argc, char** argv) {
Mat10 a;
fillRand(a, 5, 5);
prnMat(a, 5, 5);
cout << endl;
return 0;
}
void fillRand(Mat10 m, int n, int k) {
for (int i = 0; i < n; i++)
for (int j = 0; j < k; j++)
m[i][j] = rand() % 1000;
}
void prnMat(Mat10 a, int m, int n) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++)
cout << setw(8) << a[i][j];
cout << endl;
}
}
I need to sort the matrix from the beginning from the beginning. The smallest value must be at the beginning of the of the first column. The next must be below it and so on. The result must be sorted matrix - the smallest number must be at the beginning of the left column - the biggest value must be at the end of the matrix. Would you please help to solve the problem?
EDIT
Maybe I found possible solution:
void sort(int pin[10][2], int n)
{
int y,d;
for(int i=0;i<n-1;i++)
{
for(int j=0; j<n-1-i; j++)
{
if(pin[j+1][1] < pin[j][1]) // swap the elements depending on the second row if the next value is smaller
{
y = pin[j][1];
pin[j][1] = pin[j+1][1];
pin[j+1][1] = y;
d = pin[j][0];
pin[j][0] = pin[j+1][0];
pin[j+1][0] = d;
}
else if(pin[j+1][1] == pin[j][1]) // else if the two elements are equal, sort them depending on the first row
{
if(pin[j+1][0] < pin[j][0])
{
y = pin[j][1];
pin[j][1] = pin[j+1][1];
pin[j+1][1] = y;
d = pin[j][0];
pin[j][0] = pin[j+1][0];
pin[j+1][0] = d;
}
}
}
}
}
But since I'm new to programming I don't understand is this the solution?
Here is a simple example for you:
#include <vector>
#include <algorithm>
using namespace std;
//This is the comparation function needed for sort()
bool compareFunction (int i,int j)
{
return (i<j);
}
int main()
{
//let's say you have this matrix
int matrix[10][10];
//filling it with random numbers.
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
matrix[i][j] = rand() % 1000;
//Now we get all the data from the matrix into a vector.
std::vector<int> vect;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
vect.push_back(matrix[i][j]);
//and sort the vector using standart sort() function
std::sort( vect.begin(), vect.end(), compareFunction );
//Finally, we put the data back into the matrix
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
matrix[i][j] = vect.at(i*10 + j);
}
After this, the matrix will be sorted by rows:
1 2
3 4
If you want it to be sorted by cols:
1 3
2 4
You need to replace matrix[i][j] in the last cycle only with matrix[j][i]
If you need to read about the the sort() function, you can do it here
Hope this helps.
You can simply call std::sort on the array:
#include <algorithm> // for std::sort
int main() {
int mat[10][10];
// fill in the matrix
...
// sort it
std::sort(&mat[0][0], &mat[0][0]+10*10);
}