I have a matrix A with 4 rows and 3 columns and a matrix B with 8 rows and 4 columns. The coefficiants in the first column of B should denote those rows of A that I want to take for the inner product with the rows of B.
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
int main()
{
int ik, il, im;
//A Matrix
vector<vector<int>> A(4, vector<int>(3));
A={ {0, 0, 0}, {1, 1, 0}, {0, 0, 1}, {1, 1, 1} };
//B Matrix
vector<vector<int>> B(8, vector<int>(4));
B={ {1, 0, 0, 0}, {2, 1, 0, 0}, {2, 0, 1, 0}, {2, 1, 1, 0} ,{3, 0, 0, 1}, {4, 1, 0, 1}, {4, 0, 1, 1}, {4, 1, 1, 1} };
vector<int> BZI;
BZI={{1},{2},{2},{2},{3},{4},{4},{4}};
//calculate inner products
vector<vector<int>> SKP_AB(4, vector<int>(8));
int skp_temp;
for(ik=0; ik<4; ik++)
{
for(im=0; im<8; im++)
{
for(il=0; il<3; il++)
{
skp_temp=A[BZI[ik]][il]*B[im][il+1];
SKP_AB[ik][im]+=skp_temp;
}
}
}
//Ausgabe von SKP_AB
cout << "\n" << "#SKP_AB" << "\n";
for(ik=0; ik<4; ++ik)
{
for(il=0; il<8; ++il)
{
cout << setw(2) << SKP_AB[ik][il];
}
cout << "\n";
}
return 0;
}
In both BZI and the first column of B you used one based row indexing, but C++ uses zero based row indexing.
So you need to compensate, where you had BZI[ik] you needed BZI[ik]-1
Notice also how hard it was to reach that answer without being told what output you expected (only your program wasn't working) vs. how obvious it was once told what output you expected.
Related
I am trying to figure out a way to generate a sequence of arrays of integers at compile time (using constexpr functions). The sequence is this one:
// first all order 0 numbers
{0, 0, 0},
// then all order 1 numbers (total sum of figures = 1)
{1, 0, 0},
{0, 1, 0},
{0, 0, 1},
// then all order 2 numbers (total sum of figures = 2) in no specific order
{1, 1, 0},
{0, 1, 1},
{1, 0, 1},
{2, 0, 0},
{0, 2, 0},
{0, 0, 2}
// then all order 3 numbers etc... each block in no specific order
Currently I can only write the algorithm to get these arrays in another order
constexpr int M = 5; // maximum figure available, each figure will be from 0 to 5
constexpr int N = (M + 3) * (M + 2) / 2; // total number of arrays to be generated
constexpr std::array<std::array<int, 3>, N> algorithm() {
std::array<std::array<int, 3>, N> ans;
int pos = 0;
for (int i = 0; i <= M; ++i) {
for (int j = 0; j <= M - i; ++j) {
for (int k = 0; k <= M - i - j; ++k) {
ans[pos] = std::array<int, 3>{k, j, i};
++pos;
}
}
}
return ans;
}
This of course gives the arrays in a bad order:
{0, 0, 0},
{1, 0, 0},
{2, 0, 0},
{3, 0, 0},
...
I know this may be impossible to do at compile time, but maybe someone knows any tip for this kind of problems? Thanks for any help.
I have an array of integers called test containing 7 elements,I want to write an if statement to check if the 6 first values of the array are equal to a certain collection of values,what I tried was:
if (test == {1, 0, 1, 0, 0, 0} ) {
//statement(s)
}
However,the line containing the condition gives me an "expected an expression error",what am I doing wrong?
Thanks in advance.
C++17 versions using deduction guides:
std::array
std::array test{1, 0, 1, 0, 0, 0};
if(test == std::array{1, 0, 1, 0, 0, 0}) {
std::cout << "equal\n";
}
std::vector
std::vector test{1, 0, 1, 0, 0, 0};
if(test == std::vector{1, 0, 1, 0, 0, 0}) {
std::cout << "equal\n";
}
If you use std::array you can simply rely on operator==
std::array<int, 7> a1 = {1, 2, 3, 4, 5, 6, 7};
std::array<int, 7> a2 = {2, 3, 4, 5, 6, 7, 8};
std::cout << "a1 == a1 " << (a1 == a1) << std::endl;
std::cout << "a1 == a2 " << (a1 == a2) << std::endl;
However, if for some reason you need to use C-style array, then you can use std::memcmp, which will compare the arrays byte by byte:
int ca1[7] = {1, 2, 3, 4, 5, 6, 7};
int ca2[7] = {2, 3, 4, 5, 6, 7, 8};
std::cout << "ca1 == ca1 " << (std::memcmp(ca1, ca1, sizeof(ca1)) == 0) << std::endl;
std::cout << "ca1 == ca2 " << (std::memcmp(ca1, ca2, sizeof(ca1)) == 0) << std::endl;
Note that you need to compare the std::memcmpy result with 0, which means that they are equal. reference However, in this approach you should first check if the dimensions are equal.
Here is a way to do it (if your test is an std::array):
#include <algorithm>
...
std::vector<int> v({1, 0, 1, 0, 0, 0});
if( (v.size()==test.size()) && std::equal(test.begin(), test.end(), v.begin()) ) {
// statement(s)
}
or
#include <algorithm>
...
std::vector<int> v({1, 0, 1, 0, 0, 0});
if( std::equal(test.begin(), test.end(), v.begin(), v.end()) ) {
// statement(s)
}
I need to make a function which takes two parameters (two vectors of vectors) and as a result returns a vector of vectors which is a Kronecker product of two given vectors of vectors.
Whatever I do, my new vector of vectors is created by the same number (the one which should be only on the last position). For example if I have vector of vectors A: {3, -1},{0, 5} and B:{4,3,15},{0, -5, 2} my Kronecker product will be: {10, 10, 10, 10, 10, 10}, {10, 10, 10, 10, 10, 10} etc, instead of {12, 9, 45, -4, -3, -15}, {0, -15, 6, 0, 5, -2}, {0, 0, 0, 20, 15, 75}, {0, 0, 0, 0, -25, 10}
Matrix KroneckersProduct(Matrix A, Matrix B){
Matrix mat=CreateMatrix(NoRows(A)*NoRows(B),NoCols(A)*NoCols(B));
for(int i=0;i<NoRows(A)*NoRows(B);i++){
for(int j=0;j<NoCols(A)*NoCols(B);j++){
for(int k=0;k<NoRows(A);k++){
for(int l=0;l<NoRows(B);l++){
for(int m=0;m<NoCols(A);m++){
for(int n=0;n<NoCols(B);n++){
mat.at(i).at(j)=A.at(k).at(m)*B.at(l).at(n);
}
}
}
}
}
}
return mat;
}
This is the algorithm for Kronecker product. Maybe I switched v1 and v2
#include <vector>
#include <iostream>
using Matrix = std::vector<std::vector<double>>;
Matrix KroneckersProduct(Matrix v1, Matrix v2){
Matrix v(v1.size() * v2.size(), std::vector<double>(v1[0].size() * v2[0].size()));
for (std::size_t z1(0); z1 < v1.size(); ++z1) {
for (std::size_t z2(0); z2 < v2.size(); ++z2) {
for (std::size_t z3(0); z3 < v1[0].size(); ++z3) {
for (std::size_t z4(0); z4 < v2[0].size(); ++z4) {
v[z1*v2.size() + z2][z3*v2[0].size() + z4] = v1[z1][z3] * v2[z2][z4];
}
}
}
}
return v;
}
int main() {
Matrix v1{{3, -1},{0, 5}};
Matrix v2{{4,3,15}, {0, -5, 2}};
Matrix v(KroneckersProduct(v1, v2));
for (const auto& row : v) {
for (const auto& cell : row) {
std::cout << cell << " ";
}
std::cout << '\n';
}
return 0;
}
Output:
12 9 45 -4 -3 -15
0 -15 6 -0 5 -2
0 0 0 20 15 75
0 -0 0 0 -25 10
#include <iostream>
using namespace std;
enum {ROW = 7, COLUMN = 8};
void show(int matrix[][COLUMN], int, int);
int main (){
int horizontal = 0;
int vertical = 5;
int goldCoin[ROW][COLUMN] = {
{5, 1, 0, 4, 1, 1, 2, 0},
{0, 3, 2, 1, 0, 3, 0, 1},
{4, 3, 0, 6, 5, 0, 1, 0},
{3, 1, 0, 3, 4, 0, 1, 3},
{0, 5, 2, 0, 1, 1, 5, 1},
{2, 1, 6, 1, 6, 0, 2, 1},
{0, 0, 4, 3, 2, 3, 0, 2}
};
show(goldCoin[ROW][COLUMN], 1, 1);
return 0;
}
void show(int matrix[][COLUMN], int x, int y){
if(y >= COLUMN)
cout << "[error: column index is beyond array limit]" << endl;
else
cout << "[" << matrix[x][y] << "]" << endl;
}
The error is pointing to the function call 'show(goldCoin[ROW][COLUMN], 1, 1);' inside main. As a beginner I don't see any syntactical errors on that statement. Can somebody help?
In calling show(goldCoin[ROW][COLUMN], 1, 1);, you are passing an int as first argument, not 2D array, as you probably wanted to.
I believe that you meant to do show(goldCoin, 1, 1); instead.
It's the wrong way to pass in the argument. Pass in the array name identifier without the brackets:
show(goldCoin, 1, 1);
The expression goldCoin[ROW][COLUMN] represents one single value of type int in your 2D array. So you are passing int value in place of a int (*)[] value which is what the function expects. In this case this is actually reading out of bounds as there is no element with coordinates of [7][8] represented with the goldCoin[7][8] because arrays are zero indexed.
Only in function declaration / definition the signature is:
void show(int matrix[][COLUMN], int, int);
Don't confuse the two.
I have a 2d vector array which contains :
row id r b main
1 0 26 3
2 1 11 2
3 1 46 4
4 2 26 1
5 3 11 2
I want to sort every row based on its "main"-column value
smaller "main"-column.
smaller value => the entire row should be on the top.
if there is tow rows or more and there "main"-column have the same value, I want to check "r"-column.
smaller value => the entire row should be on the top.
after sorting it will look like this:
row id r b main
4 2 26 1
2 1 11 2
5 3 11 2
1 0 26 3
3 1 46 4
Try using std::sort like
using int_arr = std::array<int, 4>;
std::sort(std::begin(arr), std::end(arr), [](const int_arr& a, const int_arr& b){
return a[3] != b[3] ? a[3] < b[3] : a[1] < b[1];
});
Demo
#include <iostream>
#include <array>
#include <algorithm>
int main() {
using int_arr = std::array<int, 4>;
int_arr arr[5] = {
{1, 0, 26, 3},
{2, 1, 11, 2},
{3, 1, 46, 4},
{4, 2, 26, 1},
{5, 3, 11, 2}
};
for(const auto& i_arr : arr) {
for(const auto& i : i_arr)
std::cout<< i <<", ";
std::cout << "\n";
}
std::cout << "**************\n";
std::sort(std::begin(arr), std::end(arr), [](const int_arr& a, const int_arr& b){
return a[3] != b[3] ? a[3] < b[3] : a[1] < b[1];
});
for(const auto& i_arr : arr) {
for(const auto& i : i_arr)
std::cout<< i <<", ";
std::cout << "\n";
}
}
OutPut
1, 0, 26, 3,
2, 1, 11, 2,
3, 1, 46, 4,
4, 2, 26, 1,
5, 3, 11, 2,
**************
4, 2, 26, 1,
2, 1, 11, 2,
5, 3, 11, 2,
1, 0, 26, 3,
3, 1, 46, 4,