multiplying two dimensional arrays by passing to function - c++

I have created the code, and for some reason the elements C[0,3] and C[1,3] are returning the wrong result, although all other elements of the matrix are correct. Not sure why this is happening. Thanks!
#include <iostream>
#include <iomanip>
using namespace std;
const int ROWSA = 4,
COLSA = 3,
ROWSB = 3,
COLSB = 2;
void calc_AB(double [][COLSA], double B[][COLSB], double C[][ROWSA], int, int, int);
void display_C(double [][ROWSA], int);
int main()
{
double A[ROWSA][COLSA] = { { 5.2, 1, 9 },
{ 3.6, 7.5, 0 },
{ 8, 0, 4.4 },
{ 0.1, 2.7, 10 } },
B[ROWSB][COLSB] = { {12, 7.8},
{11, 8.9},
{10, 0.2} },
C[COLSB][ROWSA];
calc_AB(A, B, C, ROWSA, COLSB, COLSA);
display_C(C, COLSB);
return 0;
}
void calc_AB(double A[][COLSA], double B[][COLSB], double C[][ROWSA], int ROWSA, int COLSB, int COLSA)
{
for (int i = 0; i < ROWSA; i++)
{
for (int j = 0; j < COLSB; j++)
{
C[i][j] = 0;
for (int k = 0; k < COLSA; k++)
{
C[i][j] += A[i][k] * B[k][j];
}
}
}
}
void display_C(double C[][ROWSA], int COLSB)
{
for (int i = 0; i < ROWSA; i++)
{
for (int j = 0; j < COLSB; j++)
{
cout << setw(4) << C[i][j] << " ";
}
cout << endl;
}
}

Related

Working on a matrix inverter and my exponential loop is not working for some reason

I am working on a matrix inverter and I have it almost done but for some reason the function that is supposed to raise the matrix to a certain value is not working, I have isolated the function on its own and it has worked just fine. But for some reason is not working in this program
Isolated
#include <iomanip>
#include <stdio.h>
using namespace std;
void printano(double a[3][3])
{
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
cout << fixed << setprecision(2) << setw(12) << a[i][j] << " ";
cout << endl;
}
}
void powernator(double r[][3],double B[][3], int p)
{
double temp[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
int n = 3;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = B[b][d];
}
}
for (int i = 0; i < p - 1; i++)
{
int sum = 0;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
for (int k = 0; k < n; k++)
{
sum += B[b][k] * r[k][d];
}
temp[b][d] = sum;
sum = 0;
}
}
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = temp[b][d];
}
}
}
}
int main()
{
double B[3][3] = { {1, 2, 3} , {4, 5, 6} , {7, 8, 9} };
double r[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
powernator(r,B,3);
printano(r);
}
The actual code
#include <iostream>
#include <iomanip>
#include <cmath>
#include <stdio.h>
using namespace std;
void multiplinator(double x[][3], double y[][3], double z[][3]) //At the end I double check to make sure the value is correct as it needs to equal the identity matrix
{
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < 3; k++)
{
z[i][j] += x[i][k] * y[k][j];
}
}
}
}
void printinator(double a[3][3]) //prints a matrix
{
for(int i=0; i<=2; i++)
{
for(int j=0; j<=2; j++)
cout << fixed << setprecision(4) << setw(12) << a[i][j] << " ";
cout << endl;
}
cout << endl;
}
void sub(double as[3][3], double in[][3], double B[][3]) //Matrix subtraction
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
B[i][j] = in[i][j] - as[i][j];
}
void powernator(double r[][3],double B[][3], int p) //Array which is supposed to raise a matrix to a certain power
{
double temp[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
int n = 3;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = B[b][d];
}
}
for (int i = 0; i < p - 1; i++)
{
int sum = 0;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
for (int k = 0; k < n; k++)
{
sum += B[b][k] * r[k][d];
}
temp[b][d] = sum;
sum = 0;
}
}
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = temp[b][d];
}
}
}
}
void gettem(double r[][3], double in[][3], double inm[][3]) //Supposed to return the final value, aka, the inverse matrix, as a^-1 = I + B^1 +B^2...
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
inm[i][j] = in[i][j] + r[i][j];
}
}
int main()
{
double a[3][3] = { {1./2, 1, 0} , {0, 2./3, 0} , {-1./2, -1, 2./3} };
double as[3][3] ={ {1./2, 1, 0} , {0, 2./3, 0} , {-1./2, -1, 2./3} };
double in[3][3] = { {1, 0, 0} , {0, 1, 0} , {0, 0, 1} };
double B[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double r[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double inm[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double z[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
cout << "\n\t\t Original : " << endl;
printinator(a);
sub(as,in,B);
printinator(B);
powernator(r,B,2);
printinator(r); //testing the power function, not working
/*for(int n = 0; n < 20; n++) //Final part of the code commented out for debug, this loop is meant to add up B^n where n is from 1 - 20
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
r[i][j] += B[i][j];
}
gettem(r,in,inm);
cout << "\n\t\t Inverse: " << endl;
printinator(inm);
multiplinator(as,a,z);
cout << "\n\t\t multi: " << endl;
printinator(z);
*/
}
Isolated Code
powernator(r,B,3);
Actual Code.
powernator(r,B,2);
parameter p is differ..

Segmentation fault in matrix multiplication C++

I'm trying to make a function that receives as parameter two matrixes and returns the multiplication of both. But when I try to test it, it returns a segmentation fault, can anyone tell me why? And help me to fix it?
This is my function code:
#include <iostream>
#include <math.h>
#include <fstream>
#include <vector>
using namespace std;
vector<vector<double> > MMultiplication(vector<vector<double> > a, vector<vector<double> > b) {
int a_columns = a[0].size();
int a_rows = a.size();
int b_columns = b[0].size();
int b_rows = b.size();
< vector<vector<double> > result;
result.resize(a_columns);
for (int i = 0; i < m; ++i)
{
//Grow Columns by b_rows
result[i].resize(b_rows);
}
for (int p = 0; p < a_rows; p++) {
for (int q = 0; q < b_columns; q++) {
result[p][q] = 0;
}
}
if (a_columns != b_rows) {
cout << "Error: The number of columns of the first matrix needs to be equal to the number of rows of the second matrix" << endl;
return result;
}
for (int i = 0; i < a_rows; i++) { //i iterate a rows
for (int j = 0; j = b_columns; j++) //j iterates b columns
{
for (int k = 0; k < a_columns; k++) { //k goes back to a and iterates its columns
result[i][j] += a[i][k] * b[k][j]; //sums all multiplications into result[i][j]
}
}
}
return result;
}
And this is the main i'm using to test my function:
int main ()
{
vector < vector < double >>a;
int m = 4, n = 2;
//Grow rows by m
a.resize (m);
for (int i = 0; i < m; ++i)
{
//Grow Columns by n
a[i].resize (n);
}
a[0] =
{
1, 0};
a[1] =
{
1, 1};
a[2] =
{
1, 2};
a[3] =
{
1, 3};
cout << a.size () << endl;
cout << a[0].size () << endl;
vector < vector < double >>b;
int o = 2, p = 4;
b.resize (o);
for (int i = 0; i < o; i++)
{
b[i].resize (p);
}
b[0] =
{
1, 2, 3, 4};
b[1] =
{
1, 3, 5, 7};
vector < vector < double >>result = MMultiplication (a, b);
cout << result.size () << endl;
cout << result[0].size () << endl;
/* for(int k = 0; k < result.size(); k++) {
for(int q = 0; q < result[0].size(); q++)
cout << result[k][q] << endl;
} */
}
Also, it's important to point out that the function, so far, is returning a matrix of zeros if it's impossible to multiply a and b.
Thank you.

Reverse a row in a two dimensional array C++

I'm trying to reverse each row of a two dimensional array and store that in a new two dimensional array. I understand I need to use a temp pointer, but I seem to be a bit lost on how to actually do this all. I've tried researching the problem but couldn't find anything specific to mine.
using namespace std;
void compute(int *p1, int *p2, int ROWS, int COLUMNS);
int main() {
const int COLUMNS = 3;
const int ROWS = 3;
int A[ROWS][COLUMNS] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int B[ROWS][COLUMNS] ;
int *p1, *p2;
p1 = &A[0][0];
p2 = &B[0][0];
compute(p1, p2, ROWS, COLUMNS);
return 0;
}
void compute(int *p1, int *p2, int ROWS, int COLUMNS) {
int *savePtrA, *savePtrB, *temp;
savePtrA = p1;
savePtrB = p2;
temp = p1+COLUMNS;
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLUMNS; j++) {
temp = *p1;
*p2 = *p1 + 1;
p1--;
p2++;
}
}
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLUMNS; ++j) {
cout << setw(5) << *savePtrA;
savePtrA++;
}
cout << setw(10) << " ";
for (int k = 0; k < COLUMNS; ++k) {
cout << setw(5) << *savePtrB;
savePtrB++;
}
cout << setw(10) << " ";
cout << endl;
}
}
You could simply call std::reverse_copy in a loop:
#include <algorithm>
int main()
{
const int COLUMNS = 3;
const int ROWS = 3;
int A[ROWS][COLUMNS] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int B[ROWS][COLUMNS] ;
for (int i = 0; i < ROWS; ++i)
std::reverse_copy(&A[i][0], &A[i][COLUMNS], &B[i][0]);
}
Live Example
The source array is given in the first two arguments -- a pointer to the first element in the source row, and a pointer to one past the last element in the source row. The third parameter is the destination row, and that is merely a pointer to the first element in the B row.
I do not know if it is what you are looking for but change your code so that it does what you ask, although it can be done in an easier way
#include <iostream>
#include <iomanip>
using namespace std;
void compute(int *p1, int *p2, int COLUMNS);
int main() {
const int COLUMNS = 3;
const int ROWS = 3;
int A[ROWS][COLUMNS] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int B[ROWS][COLUMNS] ;
int *p1, *p2, *savePtrA, *savePtrB;
savePtrA = p1;
savePtrB = p2;
for (int i = 0; i < ROWS; ++i) {
p1 = &A[i][0];
p2 = &B[i][0];
compute(p1, p2, COLUMNS);
}
for (int i = 0; i < ROWS; ++i) {
savePtrA = &A[i][0];;
savePtrB = &B[i][0];
for (int j = 0; j < COLUMNS; ++j) {
cout << setw(5) << *savePtrA;
savePtrA++;
}
cout << setw(10) << " ";
for (int k = 0; k < COLUMNS; ++k) {
cout << setw(5) << *savePtrB;
savePtrB++;
}
cout << setw(10) << " ";
cout << endl;
}
return 0;
}
void compute(int *p1, int *p2, int COLUMNS) {
for (int j = COLUMNS-1; j >= 0; j--) {
*p2 = *(p1 + j);
p2++;
}
}

Group sum of n consecutive numbers of array

So I have an array like {1, 4, 2, 3, 5, 3, 7} and I have to make a new array containing the sums of each 3 consecutive elements like {7, 9, 10, 11, 15}.
So far I got here and I don't know what I'm doing wrong.
#include <iostream>
#include <conio.h>
using namespace std;
int a[] = {1, 1, 2, 3, 5, 3, 7};
int lung = sizeof(a)/sizeof(a[0]);
int *l = new int[10];
int calc(int *a, int m)
{
int sum = 0;
int stmax = (lung - m) - 1;
for(int st=0;st <= stmax; st++)
{
for(int i = 0; i < m; i++)
{
sum = sum + a[st+i];
}
l[st] = sum;
}
return 0;
}
void main()
{
int a[] = {1, 1, 2, 3, 5, 3, 7};
cout << calc(a, 3)<< endl;
for (int i = 0; i < lung; i++)
{
cout << l[i] << " | ";
}
_getch();
}
you have to set sum=0; after each iteration
for(int st=0;st <= stmax; st++)
{
sum=0;
for(int i = 0; i < m; i++)
{
sum = sum + a[st+i];
}
l[st] = sum;
}
and also you have to declare int stmax = (lung - m); //ommit -1
and in the main function print the array till stmax
for (int i = 0; i <= stmax; i++)
{
cout << l[i] << " | ";
}
I would do it like this:
#include <iostream>
#include <conio.h>
using namespace std;
int a[] = { 1,4,2,3,5,3,7};
int lung = sizeof(a) / sizeof(a[0]);
int *l = new int[10];
void calc(int* a, int m){
a += 1; // Increment pointer
for (int st = 0; st <m; st++){
l[st] = a[st-1]+a[st]+a[st+1];
}
}
int main(){
calc(a, lung-2);
for (auto i = 0; i < lung-2; i++){
std::cout << l[i] << " ";
}
}

vs10 compiler is this a bug?

Mat2D.h
#pragma once
#include <iostream>
#include <iomanip>
#include <assert.h>
namespace Ggicci
{
template<class T>
class Mat2D
{
private:
int _rows;
int _cols;
T** _data;
public:
Mat2D()
:_rows(0), _cols(0), _data(NULL)
{
}
Mat2D(const Mat2D<T>& rhs)
:_rows(rhs._rows), _cols(rhs._cols)
{
allocateData();
cloneData(rhs._data);
}
Mat2D(int rows, int cols)
{
initSize(rows, cols);
allocateData();
all(0);
}
Mat2D(int rows, int cols, T initValue)
{
initSize(rows, cols);
allocateData();
all(initValue);
}
Mat2D(int rows, int cols, const T* data)
{
initSize(rows, cols);
allocateData();
assignData(data);
}
~Mat2D()
{
destroyData();
}
const Mat2D& operator = (const Mat2D<T>& rhs)
{
if (this == &rhs)
{
return *this;
}
this->resize(rhs._rows, rhs._cols);
this->cloneData(rhs._data);
return *this;
}
T& operator() (int row, int col)
{
assert(row >= 0 && row < _rows && col >= 0 && col < _cols);
return _data[row][col];
}
T operator() (int row, int col) const
{
assert(row >= 0 && row < _rows && col >= 0 && col < _cols);
return _data[row][col];
}
Mat2D<T> operator * (const Mat2D<T>& rhs)
{
assert(this->_cols == rhs._rows);
int new_rows = this->_rows;
int new_cols = rhs._cols;
Mat2D<T> result(new_rows, new_cols);
for (int i = 0; i < new_rows; i++)
{
for (int j = 0; j < new_cols; j++)
{
T sum = 0;
for (int k = 0; k < this->_cols; k++)
{
sum += this->_data[i][k] * rhs._data[k][j];
}
result._data[i][j] = sum;
}
}
return result;
}
void resize(int rows, int cols)
{
destroyData();
initSize(rows, cols);
allocateData();
all(0);
}
void all(T value)
{
for (int i = 0; i < _rows; i++)
for (int j = 0; j < _cols; j++)
_data[i][j] = value;
}
private:
void initSize(int rows, int cols)
{
assert(rows > 0 && cols > 0 && rows < 65536 && cols < 65536);
_rows = rows;
_cols = cols;
}
void allocateData()
{
_data = new T*[_rows];
for(int i = 0; i < _rows; i++)
{
_data[i] = new T[_cols];
}
}
void assignData(const T* data)
{
for (int i = 0; i < _rows; i++)
{
for (int j = 0; j < _cols; j++)
{
_data[i][j] = data[i*_rows + j];
}
}
}
void cloneData(T** data)
{
for (int i = 0; i < _rows; i++)
for (int j = 0; j < _cols; j++)
_data[i][j] = data[i][j];
}
void destroyData()
{
for(int i = 0; i < _rows; i++)
delete _data[i];
delete _data;
}
/*template<class T>*/ //--> Line 158
friend std::ostream& operator << (std::ostream& out, const Mat2D<T>& rhs)
{
for(int i = 0; i < rhs._rows; i++)
{
for(int j = 0; j < rhs._cols; j++)
{
out << std::setw(12) << rhs._data[i][j];
}
out << std::endl;
}
return out;
}
};
}
main.cpp
#include <iostream>
#include <string>
#include <cmath>
#include "Mat2D.h"
using namespace std;
using namespace Ggicci;
Mat2D<float> getRotateMatrix33f(float theta, const Mat2D<float>& ref_point = Mat2D<float>(1, 2, 0.0f))
{
theta = theta / 180 * 3.1415f;
float rotate[] = {
cos(theta), -sin(theta), 0,
sin(theta), cos(theta), 0,
0, 0, 1
};
Mat2D<float> result(3, 3, rotate);
if (ref_point(0, 0) != 0 && ref_point(0, 1) != 0)
{
float dx = ref_point(0, 0);
float dy = ref_point(0, 1);
float translate_data[] = {
1, 0, 0,
0, 1, 0,
dx, dy, 1
};
float translate_inv_data[] = {
1, 0, 0,
0, 1, 0,
-dx, -dy, 1
};
Mat2D<float> translate(3, 3, translate_data);
Mat2D<float> translate_inv(3, 3, translate_inv_data);
result = translate * result * translate_inv;
}
return result;
}
int main()
{
int data_a[] = {1, 2};
int data_b[] = {2, 3, 4, 5, 6, 7, 8, 9};
Mat2D<int> a(1, 2, data_a);
Mat2D<int> b(2, 4, data_b);
Mat2D<int> c;
c = a * b;
cout << "c = " << endl << c << endl;
cout << "rotate matrix: " << endl << getRotateMatrix33f(30.0f) << endl;
return 0;
}
If I comment line 158 in Mat2D.h, every thing is okay, the project can build and run successfully though 4 errors occur:
If I don't comment line 158,
error C2995: 'std::ostream &Ggicci::operator <<(std::ostream &,const Ggicci::Mat2D<T>
&)' : function template has already been defined.
Then I comment the function getRotateMatrix33f and its invoking in main the project rebuild and run successfully with no errors.
So what happened? It confused me...
There is actually no error after commenting line 158, but C++ intellisense still think of your old code or probably mistake in parsing your code, MSVC team accepted this to be a bug in their intellisense engine but they said that they can't fix it untill MSVC2012, so if you can please test your code with that version