Im using VS2013 along with the SystemC library from Allegro. I was trying to initialize two arrays as follows:
int pathObs1[19] = {10,9,8,7,6,5,4,3,2,1,2,3,4,5,6,7,8,9,10};
int Map[10][4] = {
{ 0, 3, 1, 4 }, //Grid 1
{ 1, 3, 2, 4 }, //Grid 2
{ 2, 3, 3, 4 }, //Grid 3
{ 3, 3, 4, 4 }, //Grid 4
{ 4, 3, 5, 4 }, //Grid 5
{ 5, 3, 6, 4 }, //Grid 6
{ 6, 3, 7, 4 }, //Grid 7
{ 6, 2, 7, 3 }, //Grid 8
{ 6, 1, 7, 2 }, //Grid 9
{ 6, 0, 7, 1 } //Grid 10
};
However i received the error the above error. I saw some questions on SO which had the same issue, however I dont think they were dealing with SystemC. Any easy workaround for this in SystemC since im trying to initialize inside my SC_MODULE header/constructor?
Edit: I had a typo in my array initialization. Still get the same error.
2dArray[m][n] means m rows n columns so you can keep n values in each row but in your code you defined matrix which had 3 columns but still you are assigning 4 values.
You can use a loop for filling the array:
#include <iostream>
#include <stdlib>
int main()
{
srand(time(null));
int map[10][4];
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 4; j++)
{
map[i][j] = rand(); // you can write smth like rand() % 5 to make a limit of the values
}
}
return 0;
}
I have for example the following matrix B which is stored in COO and CSR format (retrieved from the non-symetric example here). Could you please suggest an efficient c++ way to apply the matlab sum(B,2) function using the coo or csr(or both) storing format? Because it is quit possible to work with large arrays can we do that using parallel programming (omp or CUDA (e.g, thrust))?
Any algorithmic or library based suggestions are highly appreciated.
Thank you!
PS: Code to construct a sparse matrix and get the CSR coordinates can be found for example in the answer of this post.
COO format: CSR format:
row_index col_index value columns row_index value
1 1 1 0 0 1
1 2 -1 1 3 -1
1 3 -3 3 5 -3
2 1 -2 0 8 -2
2 2 5 1 11 5
3 3 4 2 13 4
3 4 6 3 6
3 5 4 4 4
4 1 -4 0 -4
4 3 2 2 2
4 4 7 3 7
5 2 8 1 8
5 5 -5 4 -5
For COO its pretty simple:
struct MatrixEntry {
size_t row;
size_t col;
int value;
};
std::vector<MatrixEntry> matrix = {
{ 1, 1, 1 },
{ 1, 2, -1 },
{ 1, 3, -3 },
{ 2, 1, -2 },
{ 2, 2, 5 },
{ 3, 3, 4 },
{ 3, 4, 6 },
{ 3, 5, 4 },
{ 4, 1, -4 },
{ 4, 3, 2 },
{ 4, 4, 7 },
{ 5, 2, 8 },
{ 5, 5, -5 },
};
std::vector<int> sum(5);
for (const auto& e : matrix) {
sum[e.row-1] += e.value;
}
and for large matrixes you can just split up the for loop into multiple smaller ranges and add the results at the end.
If you only need the sum of each row (and not columwise) CSR is also straight forward (and even more efficient):
std::vector<int> row_idx = { 0, 3, 5, 8, 11, 13 };
std::vector<int> value = { 1, -1, -3, -2, 5, 4, 6, 4, -4, 2, 7, 8, -5 };
std::vector<int> sum(5);
for(size_t i = 0; i < row_idx.size()-1; ++i) {
sum[i] = std::accumulate(value.begin() + row_idx[i], value.begin() + row_idx[i + 1], 0);
}
Again, for parallelism you can simply split up the loop.
this is my Stata.h
#include "State.h"
#include <iostream>
using namespace std;
class State
{
public:
int data[4][4];
int x;
int y;
int cost[];
State(void);
void CopyState(State*);
bool equals(State*);
int h(State*);
void print(void);
private:
int getLocation(State, int, int);
};
and this is my State.cpp
#include "State.h"
#include <iostream>
using namespace std;
State::State(void)
{
State::cost[] = {0, 3, 2, 5, 3, 4, 1, 2, 2, 1, 4, 3,
5, 2, 3, 2, 3, 0, 3, 2, 2, 3, 2, 1,
1, 2, 1, 4, 2, 3, 2, 3, 2, 3, 0, 3,
1, 2, 3, 2, 4, 1, 2, 1, 3, 2, 3, 2,
5, 2, 3 ,0 ,2 , 1 , 4 , 3 ,3 , 4 ,1 , 2,
2, 3, 2, 5, 3, 2, 1, 2, 0, 3, 2, 3,
3, 2, 1 ,2 ,2 , 1 ,4 ,3 , 4 ,3 ,2 , 1 ,
3 ,0, 3, 2, 2 , 3, 2, 1 , 1 , 2, 1, 4,
1 , 2, 3 ,4 ,2 ,3 ,0 ,3 ,1 , 2 ,3 ,2 ,
4 ,1, 2, 1, 2, 1, 2, 3, 3, 2, 3, 0,
2 ,1, 2 , 3 ,3 ,4 ,1 ,2 , 2 , 1 ,4 ,3,
3 , 2, 1, 2, 0 , 3 , 2 , 3, 3 , 2, 1, 2,
1 ,2, 1 , 4 ,2 ,3 ,2 , 1 , 3 , 0 , 3 , 2,
4 , 3, 2 , 1 , 4 , 1, 2 , 1 , 1 , 2, 3 , 2,
2, 3 ,0 ,3 ,1 , 2 , 3 , 4 , 3 ,4 , 1 ,2,
2 ,1, 2, 3 , 3 , 2 , 3 , 0, 2, 1, 2, 3,
5 , 2 ,3 , 2 ,2 ,1 , 4 ,3 ,3 ,4 ,1 ,2,
0 ,3, 2, 5, 2 , 3 , 2, 3, 1, 2, 1, 4,
2 ,3 ,2 , 1 ,3 , 0 ,3 , 2, 3 , 2 ,3 ,2 ,
4 ,1, 2, 1, 1 , 2, 3 , 2 , 2, 3 , 0, 3,
2 ,3 ,2 , 5 , 3 , 4 , 1 , 2 , 2 , 1 ,4 , 3 ,
5 , 2 ,3 ,0
};
}
void State::CopyState(State *state)
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
data[i][j] = state->data[i][j];
x = state->x;
y = state->y;
}
bool State::equals(State *state)
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
if (data[i][j] != state->data[i][j])
return false;
return true;
}
int State::h(State *state)
{
int k = 0;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
{
int frmPos = 4 * i + j;
int toPos = getLocation(*state, i, j);
k += cost[16 * frmPos + toPos];
}
return k;
}
void State::print()
{
cout << "\n";
for (int i = 0; i < 4; i++)
{
cout << "\n";
for (int j = 0; j < 4; j++)
cout << data[i][j];
}
cout << endl;
}
the problem is in State.cpp in the constructor when I'm trying to assign values to the cost array I don't know where is the problem, please any one can solve that , sorry for my bad english
You can't do it that way. There's a couple of problems, but the first problem is this:
In the header you declare cost as an array with an unspecified size:
int cost[];
This isn't allowed in Standard C++ because now the compiler doesn't know how big the array is, and therefore doesn't know how big State will be. (Some compilers do allow it, but it's a special extension that won't work on other compilers.)
The simplest and often best way to do this is to use a vector:
#include <vector>
class State
{
// ...
std::vector <int> cost;
};
And then in the constructor:
State::State()
{
static const int startingValues [] =
{0, 3, 2, 5, 3, 4, 1, 2, 2, 1, 4, 3, ... };
static const size_t numStartingValues = sizeof (startingValues) / sizeof (startingValues [0]);
std::copy (startingValues, startingValues + numStartingValues, std::back_inserter (cost));
}
If you're using C++11, then this is made simpler with the uniform initialization syntax:
State::State()
:
cost {0, 3, 2, 5, ...}
{
}
First of all, the cost member is not an array, it is a pointer (or it was when I looked at it, but you've changed it. However, it's still not an array. It is now a compiler error.). If you want it to point to an array, first you have to allocate it. But that's a terrible idea. Change it to a vector:
class State {
...
std::vector<int> cost;
...
};
Then, in your constructor, you can initialize it like this (if your compiler supports C++11)
State::State() :
cost{0, 3, 2, 5, 3, 4} // trimmed for brevity, but you can put as many elements as you want
{}
If your compiler does not support C++11 (or does not support this feature), then you can initialize the vector like this:
State::State()
{
static int temp[] = {0, 3, 2, 5, 3, 4};
cost.assign(temp, temp + sizeof(temp) / sizeof(*temp));
}