Define matrices in an array element C++ - c++

I have written some c++ code that receives a Matrix as input and now I want to create a 2D array with matrices in each element so that I can send the individual matrices to the function.
typedef vector< vector > Matrix;
double a[2][2] = Matrix(2, vector(2));
so that each element of a is a 2x2 Matrix.
The reason I don't want to just create a 4D array with vectors is that I want to keep all of the original functions that I have already created with matrices as input.
Any way this is possible?
Here is a simple example code...
#include <stdio.h>
#include <iostream>
#include <time.h>
#include <vector>
typedef vector< vector > Matrix;
void test2D_array(int l, int m, Matrix &a, Matrix &b) {
int R = l - 1;
for (int i = 0; i < m+1; i++) {
b[l - 1][i] = a[l][i];
b[l - 2][i] = (l - 1) * a[l - 1][i];
for (int k = R-1; k > 0; k--) {
b[k - 1][i] = b[k + 1][i] + a[k][i];
}
}
}
int main(void) {
Matrix a(2, vector<double>(2));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i][j] = 1;
}
}
Matrix b(2, vector<double>(2));
test2D_array(2, 2, a, b);
// What I want to accomplish...
// Matrix a[2][2] = Matrix((2, vector<double>(2)); i.e. 4D array with each element a 2x2 matrix
// for (int i = 0; i < 2; i++) {
// for (int j = 0; j < 2; j++) {
// test2D_array(2, 2, a[i][j], b);
// }
//}
//
return 0;
}

Related

Writing a function to rotate a 2d vector 90 degrees clockwise

I am trying to rotate a 2d vector clockwise but I am unable to get it to work for vectors that are not square.
Here is what I tried
bool Pgm::Clockwise(){
int i, j, k;
vector <vector <int> > tempPixel;
for (i = 0; i < Pixels.size(); i++) {
tempPixel.push_back(Pixels.at(i));
}
for (j = 0; j < tempPixel.size(); j++) {
tempPixel.push_back(vector<int>());
for (k = 0; k < tempPixel.at(0).size(); k++) {
tempPixel.at(j).push_back(Pixels.at(j));
}
}
return true;
}
#include <vector>
std::vector<std::vector<int>> rotateClockwise(std::vector<std::vector<int>> v) {
int n = v.size();
int m = v[0].size();
// create new vector with swapped dimensions
std::vector<std::vector<int>> rotated(m, std::vector<int>(n));
// populate the new vector
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
rotated[j][n-i-1] = v[i][j];
}
}
return rotated;
}
This function takes a 2D vector as input and returns a new 2D vector that is rotated 90 degrees clockwise. It first creates a new vector rotated with dimensions swapped, then populates it by copying the elements from the input vector in the appropriate order.
i hope this will help you to get an idea..

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;
}

Matrix scalar product

I have a task to calculate a scalar product
s=(B*(r+q+r), A*A*p)
As I understand, I need to calculate 2 vectors: first - B*(r+q+r), second - AAp, and then calculate a scalar product.
#include <iostream>
#include <vector>
using namespace std;
using matrix = vector<vector<double>>;
matrix add(matrix A, matrix B) {
matrix C;
C.resize(A.size());
for (int i = 0; i< A.size(); i++) {
C[i].resize(B.size());
for (int j = 0; j < B.size(); j++) {
C[i][j] = A[i][j] + B[i][j];
}
}
return C;
}
matrix multiple(matrix A, matrix B)
{
matrix C;
C.reserve(100);
C.resize(B.size());
for (int i = 0; i < A.size(); i++) {
C[i].resize(B.size());
for (int j = 0; j < B.size(); j++) {
for (int k = 0; k < B.size(); k++)
C[i][j] += A[i][k] * B[k][j];
}
}
return C;
}
void main() {
matrix A = { {1,2,3}, {1,2,1}, {3,2,0} };
matrix B = { {4,1,2},{0,4,3},{1,1,1} };
matrix r = { {-0.7f, 1.3, 0.2} };
matrix q = { { -1.6f, 0.8, 1.1} };
matrix p = { {0.1, 1.7, -1.5} };
matrix r_q = add(r, q);
for (int i = 0; i < r_q.size(); i++) {
for (int j = 0; j < r_q.size(); j++) {
cout << r_q[i][j] << "\t";
}
cout << "\n";
}
matrix a_a = multiple(A, A);
matrix a_a_p = multiple(a_a,p);
getchar();
}
Problems:
add method work not correct, it put in result only one number - sum of the first items.
Multipling matrix with the same dimensions (A*A) work correct. Multipling matrix with the different dimensions (a_a * p) - return error "vector subscript out of range".
Thanks for any advice.
The OP chose to implement both matrices and vectors using a std::vector<std::vector<double>>.
This may not be a good design choice in general, but also in particular, to be consistent to the mathematical meaning of all the involved operations, all the vectors should be considered (and declared as well) as "column" matrices (or Nx1 matrices):
matrix r = { {-0.7}, {1.3}, {0.2} };
matrix q = { {-1.6}, {0.8}, {1.1} };
matrix p = { {0.1}, {1.7}, {-1.5} };
Then, in the functions that perform the calculations, special attention should be paid to the correct sizes of rows and columns to avoid out of bounds accesses.
matrix add(matrix const &A, matrix const &B)
{
if (A.size() != B.size() || A.size() == 0)
throw std::runtime_error("number of rows mismatch");
size_t columns = A[0].size();
matrix C(A.size(), std::vector<double>(columns, 0.0));
for (size_t i = 0; i < A.size(); i++)
{
if ( A[i].size() != columns || B[i].size() != columns )
throw std::runtime_error("number of columns mismatch");
for (size_t j = 0; j < columns; j++)
{
C[i][j] = A[i][j] + B[i][j];
}
}
return C;
}
matrix multiple(matrix const &A, matrix const &B)
{
if ( A.size() == 0 || B.size() == 0 || B[0].size() == 0)
throw std::runtime_error("size mismatch");
size_t columns = B[0].size();
matrix C(A.size(), std::vector<double>(columns, 0.0));
for (size_t i = 0; i < A.size(); i++)
{
if ( A[i].size() != B.size() || B[i].size() != columns )
throw std::runtime_error("inner size mismatch");
for (size_t j = 0; j < columns; j++)
{
for (size_t k = 0; k < B.size(); k++)
C[i][j] += A[i][k] * B[k][j];
}
}
return C;
}
The compiler should have also warned the OP about the incorrect use of void main instead of int main and about the comparisons between signed and unsigned integer expressions (I used size_t instead of int).
From a mathematical point of view, it's worth noting that to solve OP problem, that is to calculate the scalar product s = (B(r+q+r), AAp), the operations really needed (to be implemented) are the sum of vectors, the product of a matrix by a vector (easier and more efficient then matrix multiplication) and the dot product of two vectors:
t = r + q + r
b = Bt
u = Ap
a = Au
s = (b, a)

Sort Diagonally Two Dimensional Array

Firstly I created my two dimensional array, then I translated it to one dimensional array and I bubble sorted the 1D array, but after I didn't find the pattern to bring it back to 2D array diagonally sorted.
#include<iostream>
#include<iomanip>
const int r = 10;
const int c = 10;
const int lim = r * c;
int A[r][c] = { 0 };
int B[lim];
using namespace std;
void generatearray(int A[][], int r, int c){
srand(time(NULL));
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
A[i][j] = rand() % lim;
}
}
}
void transformingto1Darray(int A[r][c], int b[lim]){
int p = 0;
for (int m = 0; m < r; m++){
for (int n = 0; n < c; n++){
B[p] = A[m][n];
p++;
}
}
}
void sorting1Darray(int B[][]){
int temp = 0;
for (int k = 0; k < lim - 1; k++){
for (int i = 0; i < lim - 1; i++)
if (B[i] > B[i + 1]){
temp = B[i];
B[i] = B[i + 1];
B[i + 1] = temp;
}
}
}
void sortingdiagonally2Darray(int A[][], int B[]){
int main{
generatearray(A);
transformingto1Darray(A, B);
sorting1Darray(B);
sortingdiagonally2Darray(A, B);
return 0;
}
It's a bit of a wonky solution but it dose work. Because of the way multidimensional indexing works the value in B[i] will be equal to the value in A[0][i].
In your case you want something like this in your sortingdiagonally2Darray function.
for (int i = 0; i > r * c; i++) {
A[0][i] = B[i];
}
This works because under the hood arrays are just pointers. B[x] is syntactic sugar for *(B + x) and A[0][x] will equate to *(*(A + 0) + x) because it's a pointer to a pointer (hence the double star/double brackets).

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);
}