C++ PCA - Calculating covariance MATRIX - c++

I'm trying to calculate the Covariance (matrix) of a vector in C++ ...
I have carried out the following:
std::vector<std::vector<double> > data = { {2.5, 2.4}, {0.5, 0.7} };
I have then calculated and subtracted the mean, which gave the following result:
data = { {0.05, -0.05}, {-0.1, 0.1} }
As far as I'm aware, the next step is to transpose the matrix, and multiply the origin together, take the sum and finally divide by the dimensions X - 1..
I have written the following:
void cover(std::vector<std::vector<double> > &d)
{
double cov = 0.0;
for(unsigned i=0; (i < d.size()); i++)
{
for(unsigned j=0; (j < d[i].size()); j++)
{
cov += d[i][j] * d[j][i] / (d[i].size() - 1);
std::cout << cov << " ";
}
std::cout << std::endl;
}
}
Where d is the vector after the mean has been subtracted from each of the points
Which gives me the result:
0.0025, 0.0075
0.0125, 0.0225
Where compared with matlab:
2.0000 1.7000
1.7000 1.4450
Does anyone have any ideas to where I am going wrong?
Thanks

This statement:
As far as I'm aware, the next step is to transpose the matrix, and multiply the origin together, take the sum and finally divide by the dimensions X - 1..
And this implementation:
cov += d[i][j] * d[j][i] / (d[i].size() - 1);
Don't say the same thing. Based on the definition here:
void outer_product(vector<double> row, vector<double> col, vector<vector<double>>& dst) {
for(unsigned i = 0; i < row.size(); i++) {
for(unsigned j = 0; j < col.size(); i++) {
dst[i][j] = row[i] * col[j];
}
}
}
//computes row[i] - val for all i;
void subtract(vector<double> row, double val, vector<double>& dst) {
for(unsigned i = 0; i < row.size(); i++) {
dst[i] = row[i] - val;
}
}
//computes m[i][j] + m2[i][j]
void add(vector<vector<double>> m, vector<vector<double>> m2, vector<vector<double>>& dst) {
for(unsigned i = 0; i < m.size(); i++) {
for(unsigned j = 0; j < m[i].size(); j++) {
dst[i][j] = m[i][j] + m2[i][j];
}
}
}
double mean(std::vector<double> &data) {
double mean = 0.0;
for(unsigned i=0; (i < data.size());i++) {
mean += data[i];
}
mean /= data.size();
return mean;
}
void scale(vector<vector<double>> & d, double alpha) {
for(unsigned i = 0; i < d.size(); i++) {
for(unsigned j = 0; j < d[i].size(); j++) {
d[i][j] *= alpha;
}
}
}
So, given these definitions, we can compute the value for the covariance matrix.
void compute_covariance_matrix(vector<vector<double>> & d, vector<vector<double>> & dst) {
for(unsigned i = 0; i < d.size(); i++) {
double y_bar = mean(d[i]);
vector<double> d_d_bar(d[i].size());
subtract(d[i], y_bar, d_d_bar);
vector<vector<double>> t(d.size());
outer_product(d_d_bar, d_d_bar, t);
add(dst, t, dst);
}
scale(dst, 1/(d.size() - 1));
}

I think maybe For loop in outer_product it's wrong:
void outer_product(vector<double> row, vector<double> col, vector<vector<double>>& dst) {
for(unsigned i = 0; i < row.size(); i++) {
for(unsigned j = 0; j < col.size(); i++) {
dst[i][j] = row[i] * col[j];
}
}
I will change i++ -> j++

Related

Matrix multipication is very slow C++

I dont know why but my matrix multipication is very slow and I need to optimize it. and also the print of the matrix (1000X1000) taking long time.
The aim of the function is to calculate the matrix exponential, but my main problem is that this 2 actions are very slow for large matrices like 1000X1000.
These 2 actions implemented at poweMat() function and printeResult() function.
Here is the code:
#define M 1000
#define e 2.71828182845904523536;
//declaration of the functions
void sumMatrices(vector<vector<double> >& mat1, vector<vector<double> >& mat2);
void printResult(vector<vector<double> >&matRes);
void mulMatWithFactorial(long factorialValue);
long factorialCalculate(int n);
void initializeMatrix();
void initializeIdenticalMatrix();
void checkIfTheMatrixIsDiagonal();
void calculateExpoMatrixWithDiagonalMatrix();
void readMatrixFromFile();
void powerMat(vector<vector<double> >& mat, int powNum);
//declaration of the variables
vector<vector<double>> inputMatrix(M, vector<double>(M));
vector<vector<double>> sumMatrixResult(M, vector<double>(M));
vector<vector<double>> powerMatrixResult(M, vector<double>(M));
vector<vector<double>> mulFactorialMatrixResult(M, vector<double>(M));
vector<vector<double>> finalMatrixResult(M, vector<double>(M));
vector<vector<double>> identicalMatrix(M, vector<double>(M));
vector<vector<vector<double>>> listOfMatrices;
bool matrixIsNilpotent = false;
int diagonaMatrixlFlag = 1;
int main() {
//variables
long factorialValue;
initializeIdenticalMatrix();
readMatrixFromFile();
//check if the matrix is diagonal - so we will have easier and faster compute
checkIfTheMatrixIsDiagonal();
if (diagonaMatrixlFlag == 1) {
calculateExpoMatrixWithDiagonalMatrix();
goto endOfLoop;
}
//loop for taylor series
for (int i = 0; i < 5; i++) {
if (i == 0) { // first we add identical matrix when the power is 0
sumMatrices(finalMatrixResult, identicalMatrix); // summarize between this 2 matrices
finalMatrixResult = sumMatrixResult; //copy matrices
}
if (i == 1) { // we add the matrix itself because the power is 1
sumMatrices(finalMatrixResult, inputMatrix);
finalMatrixResult = sumMatrixResult; //copy matrices
}
if (i > 1 ) {
powerMat(inputMatrix, i);
if (matrixIsNilpotent) { // it means that A^i is 0 for some integer, so the series terminates after a finite number
goto endOfLoop;
}
factorialValue = factorialCalculate(i); // calculate the factorial of i
mulMatWithFactorial(factorialValue); // multiply (1/i) * matrix^i - like in the algorithm
sumMatrices(finalMatrixResult, mulFactorialMatrixResult); // summarize it with the previous result
finalMatrixResult = sumMatrixResult; //copy matrices
}
}
endOfLoop:
printResult(finalMatrixResult); // print the final result - e^M
return 0;
}
//Summarize matrices
void sumMatrices(vector<vector<double> >& mat1, vector<vector<double> >& mat2) {
for (int i = 0; i < M; i++)
for (int j = 0; j < M; j++)
sumMatrixResult[i][j] = mat1[i][j] + mat2[i][j];
}
//Print matrix
void printResult(vector<vector<double> >& matRes) {
for (int i = 0; i < M; i++) {
for (int j = 0; j < M; j++) {
printf("%f ", matRes[i][j]);
if (j == M - 1) {
printf("\n");
}
}
}
}
//Calculate the factorial of n
long factorialCalculate(int n) {
long factorial = 1.0;
for (int i = 1; i <= n; ++i) {
factorial *= i;
}
return factorial;
}
// mutiply the matrix with scalar
void mulMatWithFactorial(long factorialValue) {
for (int i = 0; i < M; i++) {
for (int j = 0; j < M; j++) {
mulFactorialMatrixResult[i][j] = powerMatrixResult[i][j] * 1/factorialValue;
}
}
}
//initialize matrix
void initializeMatrix() {
for (int i = 0; i < M; i++) {
for (int j = 0; j < M; j++) {
powerMatrixResult[i][j] = 0;
}
}
}
void checkIfTheMatrixIsDiagonal() {
for (int i = 0; i < M; i++) {
for (int j = 0; j < M; j++) {
if (i == j)
{
if (inputMatrix[i][j] == 0) {
diagonaMatrixlFlag = 0;
goto endOfLoop;
}
}
else
{
if (inputMatrix[i][j] != 0) {
diagonaMatrixlFlag = 0;
goto endOfLoop;
}
}
}
}
endOfLoop:
return;
}
void calculateExpoMatrixWithDiagonalMatrix() {
for (int i = 0; i < M; i++) {
for (int j = 0; j < M; j++) {
if (i == j)
{
for (int k = 0; k < inputMatrix[i][j]; ++k)// loop to calculate the pow of e^alpha
{
finalMatrixResult[i][j] *= e;
}
}
else
{
finalMatrixResult[i][j] = 0;
}
}
}
}
void readMatrixFromFile() {
ifstream f("inv_matrix(1000x1000).txt");
for (int i = 0; i < M; i++)
for (int j = 0; j < M; j++) {
f >> inputMatrix[i][j];
if (f.peek() == ',')
f.ignore();
}
listOfMatrices.push_back(inputMatrix);
}
void initializeIdenticalMatrix() {
for (int i = 0; i < M; i++) {
for (int k = 0; k < M; k++) {
if (i == k) {
identicalMatrix[i][k] = 1;
}
else {
identicalMatrix[i][k] = 0;
}
}
}
}
void powerMat(vector<vector<double> >& mat, int powNum) {
int counterForNilpotent = 0;
initializeMatrix();
auto start = high_resolution_clock::now();
for (int i = 0; i < M; i++) {
for (int k = 0; k < M; k++) {
for (int j = 0; j < M; j++) {
powerMatrixResult[i][j] += mat[i][k] * listOfMatrices[powNum-2][k][j];
}
}
}
auto stop = high_resolution_clock::now();
auto duration = duration_cast<seconds>(stop - start);
cout << duration.count() << " seconds" << endl; // checking run time
listOfMatrices.push_back(powerMatrixResult);
// check if after we we did A^i , the matrix is equal to 0
for (int i = 0; i < M; i++) {
for (int j = 0; j < M; j++) {
if (powerMatrixResult[i][j] == 0) {
counterForNilpotent++;
}
}
}
if (counterForNilpotent == M * M) {
matrixIsNilpotent = true;
}
}
Going through each element of an array of size "n" will have some computational efficiency of O(n^2), meaning for large arrays it will take a while but won't be "life-time-of-the-universe" lengths of time.
Usually to do operations on massive arrays like this, they're reduced in some form first so that the computation can be closer to O(n) or better using some truths about reduced forms of matrices.
So, a faster implementation for matrix multiplication would start with some rref() function upon both matrices and then only evaluating parts of those matrices that would have objects in the columns and rows.
Here are some great places to review/learn (for free) Linear Algebra:
"3b1b (2016): Essence of Linear Algebra" = https://www.youtube.com/watch?v=kjBOesZCoqc&list=PL0-GT3co4r2y2YErbmuJw2L5tW4Ew2O5B
"MIT OpenCourseWare (2009): Linear Algebra" = https://www.youtube.com/watch?v=ZK3O402wf1c&list=PL49CF3715CB9EF31D&index=1
Use SSE2. It’s not a library. It’s a method to use cpu vector hardware.
You set up operations to run in parallel.
https://en.wikipedia.org/wiki/SSE2

Pascal triangle matrix using vectors in C++

I need make Pascal Triangle matrix using vectors and then print it.
This algorithm would work with arrays, but somehow it doesn't work with matrix using vectors.
#include <iomanip>
#include <iostream>
#include <vector>
typedef std::vector<std::vector<int>> Matrix;
int NumberOfRows(Matrix m) { return m.size(); }
int NumberOfColumns(Matrix m) {
if (m.size() != 0)
return m[0].size();
return 0;
}
Matrix PascalTriangle(int n) {
Matrix mat;
int a;
for (int i = 1; i <= n; i++) {
a = 1;
for (int j = 1; j <= i; j++) {
if (j == 1)
mat.push_back(j);
else
mat.push_back(a);
a = a * (i - j) / j;
}
}
return mat;
}
void PrintMatrix(Matrix m, int width) {
for (int i = 0; i < NumberOfRows(m); i++) {
for (int j = 0; j < NumberOfColumns(m); j++)
std::cout << std::setw(width) << m[i][j];
std::cout << std::endl;
}
}
int main() {
Matrix m = PascalTriangle(7);
PrintMatrix(m, 10);
return 0;
}
I get nothing on screen, and here's the same code just without matrix using vectors program (which works fine).
Could you help me fix this code?
The main problem is that in PascalTriangle, you are starting out with an empty Matrix in both the number of rows and columns.
Since my comments mentioned push_back, here is the way to use it if you did not initialize the Matrix with the number of elements that are passed in.
The other issue is that NumberOfColumns should specify the row, not just the matrix vector.
The final issue is that you should be passing the Matrix by const reference, not by value.
Addressing all of these issues, results in this:
Matrix PascalTriangle(int n)
{
Matrix mat;
for (int i = 0; i < n; i++)
{
mat.push_back({}); // creates a new empty row
std::vector<int>& newRow = mat.back(); // get reference to this row
int a = 1;
for (int j = 0; j < i + 1; j++)
{
if (j == 0)
newRow.push_back(1);
else
newRow.push_back(a);
a = a * (i - j) / (j + 1);
}
}
return mat;
}
And then in NumberOfColumns:
int NumberOfColumns(const Matrix& m, int row)
{
if (!m.empty())
return m[row].size();
return 0;
}
And then, NumberOfRows:
int NumberOfRows(const Matrix& m) { return m.size(); }
And last, PrintMatrix:
void PrintMatrix(const Matrix& m, int width)
{
for (int i = 0; i < NumberOfRows(m); i++)
{
for (int j = 0; j < NumberOfColumns(m, i); j++)
std::cout << std::setw(width) << m[i][j];
std::cout << std::endl;
}
}
Here is a live demo
Your code won't compile because you have numerous errors in PascalTriangle.
For one, you initialize a matrix with no elements. Additionally, you use matrix indices starting at 1 rather than 0.
The following prints things for me:
Matrix PascalTriangle(int n) {
Matrix mat(n, std::vector<int>(n, 0)); // Construct Matrix Properly
int a;
for (int i = 0; i < n; i++) { // Start index at 0
a = 1;
for (int j = 0; j < i + 1; j++) { // Start index at 0
if (j == 0) // Changed 1 to 0
mat[i][j] = 1;
else
mat[i][j] = a;
a = a * (i - j) / (j+1); // Changed j to j+1 since j starts at 0
}
}
return mat;
}

C++ - Calculating the inverse of a matrix

I've tried to write a program that should be able to calculate the inverse of a matrix:
Here's what I have so far:
#include <iostream>
#include <vector>
#include <math.h>
#include <iomanip>
#include <stdexcept>
double getDeterminant(const std::vector<std::vector<double>> vect) {
if(vect.size() != vect[0].size()) {
throw std::runtime_error("Matrix is not quadratic");
}
int dimension = vect.size();
if(dimension == 0) {
return 1;
}
if(dimension == 1) {
return vect[0][0];
}
//Formula for 2x2-matrix
if(dimension == 2) {
return vect[0][0] * vect[1][1] - vect[0][1] * vect[1][0];
}
double result = 0;
int sign = 1;
for(int i = 0; i < dimension; i++) {
//Submatrix
std::vector<std::vector<double>> subVect(dimension - 1, std::vector<double> (dimension - 1));
for(int m = 1; m < dimension; m++) {
int z = 0;
for(int n = 0; n < dimension; n++) {
if(n != i) {
subVect[m-1][z] = vect[m][n];
z++;
}
}
}
//recursive call
result = result + sign * vect[0][i] * getDeterminant(subVect);
sign = -sign;
}
return result;
}
std::vector<std::vector<double>> getTranspose(const std::vector<std::vector<double>> matrix1) {
//Transpose-matrix: height = width(matrix), width = height(matrix)
std::vector<std::vector<double>> solution(matrix1[0].size(), std::vector<double> (matrix1.size()));
//Filling solution-matrix
for(size_t i = 0; i < matrix1.size(); i++) {
for(size_t j = 0; j < matrix1[0].size(); j++) {
solution[j][i] = matrix1[i][j];
}
}
return solution;
}
std::vector<std::vector<double>> getCofactor(const std::vector<std::vector<double>> vect) {
if(vect.size() != vect[0].size()) {
throw std::runtime_error("Matrix is not quadratic");
}
std::vector<std::vector<double>> solution(vect.size(), std::vector<double> (vect.size()));
std::vector<std::vector<double>> subVect(vect.size() - 1, std::vector<double> (vect.size() - 1));
for(std::size_t i = 0; i < vect.size(); i++) {
for(std::size_t j = 0; j < vect[0].size(); j++) {
int p = 0;
for(size_t x = 0; x < vect.size(); x++) {
if(x == i) {
continue;
}
int q = 0;
for(size_t y = 0; y < vect.size(); y++) {
if(y == j) {
continue;
}
subVect[p][q] = vect[x][y];
q++;
}
p++;
}
solution[i][j] = pow(-1, i + j) * getDeterminant(subVect);
}
}
return solution;
}
std::vector<std::vector<double>> getInverse(const std::vector<std::vector<double>> vect) {
if(getDeterminant(vect) == 0) {
throw std::runtime_error("Determinant is 0");
}
double d = 1.0/getDeterminant(vect);
std::vector<std::vector<double>> solution(vect.size(), std::vector<double> (vect.size()));
for(size_t i = 0; i < vect.size(); i++) {
for(size_t j = 0; j < vect.size(); j++) {
solution[i][j] = vect[i][j] * d;
}
}
return getTranspose(getCofactor(solution));
}
void printMatrix(const std::vector<std::vector<double>> vect) {
for(std::size_t i = 0; i < vect.size(); i++) {
for(std::size_t j = 0; j < vect[0].size(); j++) {
std::cout << std::setw(8) << vect[i][j] << " ";
}
std::cout << "\n";
}
}
int main() {
std::vector<std::vector<double>> matrix(3, std::vector<double> (3));
matrix = {
{1,2,3},
{4,5,6},
{7,8,8}
};
printMatrix(getInverse(matrix));
return 0;
}
The functions for calculating the determinant, the transpose- and the cofactor-matrix work correctly (as far as I can see), but the function for calculating the inverse-matrix doesn't.
I searched the internet and found this, which uses the same function for calculating the inverse.
Is this formula incorrect, or do you have any other idea, why it doesnt work?
The matrix I am using is
and the inverse of it should be
First of all, thanks for your comments.
The problem was the order of execution.
The correct solution is:
std::vector<std::vector<double>> getInverse(const std::vector<std::vector<double>> vect) {
if(getDeterminant(vect) == 0) {
throw std::runtime_error("Determinant is 0");
}
double d = 1.0/getDeterminant(vect);
std::vector<std::vector<double>> solution(vect.size(), std::vector<double> (vect.size()));
for(size_t i = 0; i < vect.size(); i++) {
for(size_t j = 0; j < vect.size(); j++) {
solution[i][j] = vect[i][j];
}
}
solution = getTranspose(getCofactor(solution));
for(size_t i = 0; i < vect.size(); i++) {
for(size_t j = 0; j < vect.size(); j++) {
solution[i][j] *= d;
}
}
return solution;
}
I know this is an old question but your code does not work when the input matrix's dimension is 1. Here is a workaround that I used:
vector<vector<double>> inverse(const vector<vector<double>> A) {
double d = 1.0/det(A);
vector<vector<double>> solution(A.size(), vector<double> (A.size()));
if(A.size() == 1){
vector<double> ans = {0};
ans[0] = 1.0/det(A);
solution[0] = ans;
return solution;
}
for(size_t i = 0; i < A.size(); i++) {
for(size_t j = 0; j < A.size(); j++) {
solution[i][j] = A[i][j] * d;
}
}
return transpose(cofactor(solution));
}

How to Fix LU Decompostion?

I wrote the code according to the algorithm, but the result is incorrect. According to the algorithm, we must indicate the dimension of the matrix and manually fill in the main matrix A and vector B. We need to generate an LU matrix. It is generated, but with the wrong numbers. And in the end we have to get the vector X with solutions. And this is in windowed mode.
https://imgur.com/TSsjMXp
int N = 1; // matrix dimension
double R = 0;
typedef double Matrix [6][6];
typedef double Vec [6];
.
.
.
void Decomp (Matrix A, int N, int &Change)
{
int i, j, k ;
double R, L, U;
Change = 1;
R = Math::Abs(A[1][1]);
for(j=2; j<=N; j++)
if (Math::Abs(A[j][1])>= R)
{
Change = j;
R = Math::Abs(A[j][1]);
}
if (R<= 1E-7)
{
MessageBox::Show("The system is degenerate");
}
if (k!=1)
{
for(i=1; i<=N; i++)
{
R = A[Change][i];
A[Change][i] = A[1][i];
A[1][i] = R;
}
}
for(i=2; i<=N; i++)
A[1][i] = A[1][i]/A[1][1];
for(i=2; i<=N; i++)
{
for(k=i; k<=N; k++);
{
R = 0;
for ( j=1; j<=(i-1); j++)
R = R + A[k][j] * A[j][i];
A[k][i] = A[k][i] - R;
}
if (A[i][i]<= 1E-7)
{
MessageBox::Show("The system is degenerate[enter image description here][1]");
}
for(k = i+1; k<=N; k++)
{
R = 0;
for (j=1; j<=(i-1); j++)
R = R + A[i][j] * A[j][k];
A[i][k] = (A[i][k] - R) / A[i][i];
}
}
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
C_matrix_dgv->Rows[i]->Cells[j] -> Value = Convert::ToString(A[i+1][j+1]);
}
}
void Solve (Matrix A, Vec b, Vec x, int Change, int N)
{
int i = 0,j = 0;
double R;
if (Change!=1)
{
R = b[Change];
b[Change] = b[1];
b[1] = R;
}
b[1] = b[1]/A[1][1];
for(i=2; i<=N; i++)
{
R = 0;
for( j=1; j<=(i-1); j++)
R = R + A[i][j] * b[j];
b[i] = (b[i] - R) / A[i][i];
}
x[N] = b[N];
for( i=1; i<=(N-1); i++)
{
R = 0;
for(j = (N+1-i); j<=N; j++)
R = R + A[N - i][j] * x[j];
x[N - i] = b[N - i] - R;
}
}
int N = 1; // matrix dimension
If you use this in the rest of the code you cannot get correct results. The dimension of the matrix is 6x6. Use a std::array or std::vector so that you dont need to keep the size in a seperate variable.

C++ replacing matrix values with sub-matrix values

I have a University assignment whereby I have a 1D array, containing 262144 values. I've created a matrix class which places these values into an object with the datasource being the double* list of 262144 values.
I need to be able to obtain a sub-matrix (which I'm able to do) from ANOTHER set of 262144 values (which I've also placed into a matrix object).
However, I'm having serious trouble and I've been trying so hard for the last 3 days to try and replace original matrix values from a sub-matrix. I've tried passing by reference, creating Matrix*'s. I've tried everything we've been taught and even researched a few more methods, all of which I haven't understood. I'll throw my code in here to see if anyone can explain a method to me which will be able to do this.
Matrix::Matrix()
{
"Matrix::Matrix() is invoked";
}
Matrix::Matrix(const Matrix& m)
{
"Matrix::Matrix(const Matrix&) is invoked";
_M = m._M;
_N = m._N;
_data = new double[_M*_N];
for (int i = 0; i < _M*_N; i++)
{
_data[i] = m._data[i];
}
}
Matrix::Matrix(int sizeR, int sizeC, double *input_data)
{
"Matrix::Matrix(int sizeR, int sizeC, double *input_data is invoked";
_M = sizeR;
_N = sizeC;
_data = new double[_M*_N];
for (int i = 0; i < _M*_N; i++)
{
_data[i] = input_data[i];
}
}
Matrix Matrix::get_Block(int start_row, int end_row, int start_coloumn, int end_coloumn)
{
int rows = (end_row - start_row);
int columns = (end_coloumn - start_coloumn);
int ctr = 0;
double *temp_Data = new double[rows*columns];
for (int x = start_row; x < (rows + start_row); x++)
{
for (int y = start_coloumn; y < (columns + start_coloumn); y++)
{
temp_Data[ctr] = get(x, y);
ctr++;
}
}
Matrix block(rows, columns, temp_Data);
delete[] temp_Data;
return block;
}
Matrix Matrix::operator+(const Matrix & other)
{
Matrix temp;
temp._M = other._M;
temp._N = other._N;
temp._data = new double[temp._M*temp._N];
for (int x = 0; x < (temp._M*temp._N); x++)
{
temp._data[x] = this->_data[x] + other._data[x];
}
return temp;
}
Matrix Matrix::operator*(const Matrix & other)
{
Matrix temp;
temp._M = other._M;
temp._N = other._N;
temp._data = new double[temp._M*temp._N];
for (int x = 0; x < (temp._M*temp._N); x++)
{
temp._data[x] = this->_data[x] * other._data[x];
}
return temp;
}
Matrix Matrix::operator-(const Matrix & other)
{
Matrix temp;
temp._M = other._M;
temp._N = other._N;
temp._data = new double[temp._M*temp._N];
for (int x = 0; x < (temp._M*temp._N); x++)
{
temp._data[x] = this->_data[x] - other._data[x];
}
return temp;
}
void Matrix::replace_Block(Matrix& noisy, Matrix& shuffled,int k, int j, int i)
{
int val_to_replace = 0;
for (int i = 0; i < 3 * 3; i++)
{
val_to_replace = shuffled.get(i, j);
noisy.set(i, j, val_to_replace);
}
}
void Matrix::set_Block(Matrix block, Matrix& Noisy, int start_row, int end_row)
{
int ctr = 0;
int ctr2 = 0;
int ctr3 = 0;
for (int i = 0; i < 3; i++)
{
Noisy._data[(start_row*_M)+i+4] = block.get(i, ctr);
ctr++;
}
for (int j = 0; j < 3; j++)
{
Noisy._data[((start_row + 1)*_M) + j + 3] = block.get(j, ctr2);
ctr2++;
}
for (int j = 0; j < 3; j++)
{
Noisy._data[((start_row + 1)*_M) + j + 2] = block.get(j, ctr3);
ctr3++;
}
}
double Matrix::get_Sum(Matrix m)
{
double total = 0;
short row = m.get_M();
short column = m.get_N();
for (int j = 0; j < row; j++)
{
for (int i = 0; i < column; i++)
{
total += m.get(j,i);
}
}
return total;
}
double Matrix::get_Sum(Matrix* m)
{
double total = 0;
short row = m->get_M();
short column = m->get_N();
for (int j = 0; j < row; j++)
{
for (int i = 0; i < column; i++)
{
total += m->get(i, j);
}
}
return total;
}
double Matrix::get(int i, int j)
{
return _data[(i * _M) + j];
}
void Matrix::write_Block(int i, int j)
{
for (int ctr = 0; ctr < i; ctr++)
{
for (int ctr2 = 0; ctr2 < j; ctr2++)
{
std::cout << " " << this->get(ctr,ctr2);
}
std::cout << std::endl;
}
}
void Matrix::set(int i, int j, double val)
{
this->_data[(i*_M) + j] = val;
}
void Matrix::set_N(int N)
{
_N = N;
}
void Matrix::set_M(int M)
{
_M = M;
}
int Matrix::get_N()
{
return _N;
}
int Matrix::get_M()
{
return _M;
}
Matrix::~Matrix()
{
"Matrix::~Matrix() is invoked";
delete[] _data;
}
If it would be helpful to see main() I can supply that too, however all it really contains is the creation of the matrix objects using overloaded constructors.
explanation
Answer is only 4 years late . . .
Anyway. Maybe it will help somebody else. The secret is to use a std::valarray. With that it is utmost simple to work on a matrix. And, many many functions are available.
All the functions that you want to implement are already available.
And you sub-matrix coy can be a one liner . . .
Please see example code:
#include <iostream>
#include <algorithm>
#include <numeric>
#include <valarray>
#include <iomanip>
constexpr size_t NRows = 6;
constexpr size_t NCols = 8;
constexpr size_t SubNRows = 2;
constexpr size_t SubNCols = 3;
void debugPrint(std::valarray<int> &v, size_t nrows = NRows, size_t ncols = NCols)
{
for (int r = 0; r < nrows; ++r) {
for (int c = 0; c < ncols; ++c)
std::cout << std::setw(3) << v[r*ncols+c] << ' ';
std::cout << '\n';
}
std::cout << '\n';
}
int main()
{
std::valarray<int> v1(NRows * NCols); // Define array with given size
std::iota(std::begin(v1),std::end(v1),0); // Fill the array with consecutive nunbers
debugPrint (v1); // Print the result
std::cout << "\nSum = " << v1.sum() << "\n\n"; // Print the sum of all values in matrix
std::valarray<int> v2(v1); // Create a 2nd matrix as a copy to the first
v2 += 100; // Add 100 to each value in the matrix
debugPrint(v2);
std::valarray<int> v3(NCols); // Get one column
v3 = v1[std::slice(2,NRows,NCols)];
debugPrint(v3,NRows,1);
std::valarray<int> subV2(SubNRows*SubNCols); // So, now the sub array
subV2 = v2[std::gslice(12,{SubNRows, SubNCols},{NCols,1})]; // Slice it out
debugPrint(subV2, SubNRows, SubNCols);
v1[std::gslice(25,{SubNRows, SubNCols},{NCols,1})] = subV2; // And copy to the first array
debugPrint (v1);
return 0;
}